mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Initial
This commit is contained in:
parent
8a11870c40
commit
940a0f2cad
27 changed files with 2222 additions and 0 deletions
74
Mage.Player.AI/build.xml
Normal file
74
Mage.Player.AI/build.xml
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- You may freely edit this file. See commented blocks below for -->
|
||||||
|
<!-- some examples of how to customize the build. -->
|
||||||
|
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||||
|
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||||
|
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||||
|
<!-- the Compile on Save feature is turned off for the project. -->
|
||||||
|
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||||
|
<!-- in the project's Project Properties dialog box.-->
|
||||||
|
<project name="Mage.Player.AI" default="default" basedir=".">
|
||||||
|
<description>Builds, tests, and runs the project Mage.Player.AI.</description>
|
||||||
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
There exist several targets which are by default empty and which can be
|
||||||
|
used for execution of your tasks. These targets are usually executed
|
||||||
|
before and after some main targets. They are:
|
||||||
|
|
||||||
|
-pre-init: called before initialization of project properties
|
||||||
|
-post-init: called after initialization of project properties
|
||||||
|
-pre-compile: called before javac compilation
|
||||||
|
-post-compile: called after javac compilation
|
||||||
|
-pre-compile-single: called before javac compilation of single file
|
||||||
|
-post-compile-single: called after javac compilation of single file
|
||||||
|
-pre-compile-test: called before javac compilation of JUnit tests
|
||||||
|
-post-compile-test: called after javac compilation of JUnit tests
|
||||||
|
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||||
|
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||||
|
-pre-jar: called before JAR building
|
||||||
|
-post-jar: called after JAR building
|
||||||
|
-post-clean: called after cleaning build products
|
||||||
|
|
||||||
|
(Targets beginning with '-' are not intended to be called on their own.)
|
||||||
|
|
||||||
|
Example of inserting an obfuscator after compilation could look like this:
|
||||||
|
|
||||||
|
<target name="-post-compile">
|
||||||
|
<obfuscate>
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</obfuscate>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
For list of available properties check the imported
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
|
||||||
|
Another way to customize the build is by overriding existing main targets.
|
||||||
|
The targets of interest are:
|
||||||
|
|
||||||
|
-init-macrodef-javac: defines macro for javac compilation
|
||||||
|
-init-macrodef-junit: defines macro for junit execution
|
||||||
|
-init-macrodef-debug: defines macro for class debugging
|
||||||
|
-init-macrodef-java: defines macro for class execution
|
||||||
|
-do-jar-with-manifest: JAR building (if you are using a manifest)
|
||||||
|
-do-jar-without-manifest: JAR building (if you are not using a manifest)
|
||||||
|
run: execution of project
|
||||||
|
-javadoc-build: Javadoc generation
|
||||||
|
test-report: JUnit report generation
|
||||||
|
|
||||||
|
An example of overriding the target for project execution could look like this:
|
||||||
|
|
||||||
|
<target name="run" depends="Mage.Player.AI-impl.jar">
|
||||||
|
<exec dir="bin" executable="launcher.exe">
|
||||||
|
<arg file="${dist.jar}"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
Notice that the overridden target depends on the jar target and not only on
|
||||||
|
the compile target as the regular run target does. Again, for a list of available
|
||||||
|
properties which you can use, check the target you are overriding in the
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
-->
|
||||||
|
</project>
|
BIN
Mage.Player.AI/build/classes/mage/player/ai/Attackers.class
Normal file
BIN
Mage.Player.AI/build/classes/mage/player/ai/Attackers.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Mage.Player.AI/build/classes/mage/player/ai/ComputerPlayer.class
Normal file
BIN
Mage.Player.AI/build/classes/mage/player/ai/ComputerPlayer.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Mage.Player.AI/dist/Mage.Player.AI.jar
vendored
Normal file
BIN
Mage.Player.AI/dist/Mage.Player.AI.jar
vendored
Normal file
Binary file not shown.
33
Mage.Player.AI/dist/README.TXT
vendored
Normal file
33
Mage.Player.AI/dist/README.TXT
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
========================
|
||||||
|
BUILD OUTPUT DESCRIPTION
|
||||||
|
========================
|
||||||
|
|
||||||
|
When you build an Java application project that has a main class, the IDE
|
||||||
|
automatically copies all of the JAR
|
||||||
|
files on the projects classpath to your projects dist/lib folder. The IDE
|
||||||
|
also adds each of the JAR files to the Class-Path element in the application
|
||||||
|
JAR files manifest file (MANIFEST.MF).
|
||||||
|
|
||||||
|
To run the project from the command line, go to the dist folder and
|
||||||
|
type the following:
|
||||||
|
|
||||||
|
java -jar "Mage.Player.AI.jar"
|
||||||
|
|
||||||
|
To distribute this project, zip up the dist folder (including the lib folder)
|
||||||
|
and distribute the ZIP file.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* If two JAR files on the project classpath have the same name, only the first
|
||||||
|
JAR file is copied to the lib folder.
|
||||||
|
* Only JAR files are copied to the lib folder.
|
||||||
|
If the classpath contains other types of files or folders, none of the
|
||||||
|
classpath elements are copied to the lib folder. In such a case,
|
||||||
|
you need to copy the classpath elements to the lib folder manually after the build.
|
||||||
|
* If a library on the projects classpath also has a Class-Path element
|
||||||
|
specified in the manifest,the content of the Class-Path element has to be on
|
||||||
|
the projects runtime path.
|
||||||
|
* To set a main class in a standard Java project, right-click the project node
|
||||||
|
in the Projects window and choose Properties. Then click Run and enter the
|
||||||
|
class name in the Main Class field. Alternatively, you can manually type the
|
||||||
|
class name in the manifest Main-Class element.
|
BIN
Mage.Player.AI/dist/lib/Mage.jar
vendored
Normal file
BIN
Mage.Player.AI/dist/lib/Mage.jar
vendored
Normal file
Binary file not shown.
3
Mage.Player.AI/manifest.mf
Normal file
3
Mage.Player.AI/manifest.mf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
X-COMMENT: Main-Class will be added automatically by build
|
||||||
|
|
704
Mage.Player.AI/nbproject/build-impl.xml
Normal file
704
Mage.Player.AI/nbproject/build-impl.xml
Normal file
|
@ -0,0 +1,704 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
*** GENERATED FROM project.xml - DO NOT EDIT ***
|
||||||
|
*** EDIT ../build.xml INSTEAD ***
|
||||||
|
|
||||||
|
For the purpose of easier reading the script
|
||||||
|
is divided into following sections:
|
||||||
|
|
||||||
|
- initialization
|
||||||
|
- compilation
|
||||||
|
- jar
|
||||||
|
- execution
|
||||||
|
- debugging
|
||||||
|
- javadoc
|
||||||
|
- junit compilation
|
||||||
|
- junit execution
|
||||||
|
- junit debugging
|
||||||
|
- applet
|
||||||
|
- cleanup
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Mage.Player.AI-impl">
|
||||||
|
<fail message="Please build using Ant 1.7.1 or higher.">
|
||||||
|
<condition>
|
||||||
|
<not>
|
||||||
|
<antversion atleast="1.7.1"/>
|
||||||
|
</not>
|
||||||
|
</condition>
|
||||||
|
</fail>
|
||||||
|
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
|
||||||
|
<!--
|
||||||
|
======================
|
||||||
|
INITIALIZATION SECTION
|
||||||
|
======================
|
||||||
|
-->
|
||||||
|
<target name="-pre-init">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init" name="-init-private">
|
||||||
|
<property file="nbproject/private/config.properties"/>
|
||||||
|
<property file="nbproject/private/configs/${config}.properties"/>
|
||||||
|
<property file="nbproject/private/private.properties"/>
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init,-init-private" name="-init-user">
|
||||||
|
<property file="${user.properties.file}"/>
|
||||||
|
<!-- The two properties below are usually overridden -->
|
||||||
|
<!-- by the active platform. Just a fallback. -->
|
||||||
|
<property name="default.javac.source" value="1.4"/>
|
||||||
|
<property name="default.javac.target" value="1.4"/>
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
|
||||||
|
<property file="nbproject/configs/${config}.properties"/>
|
||||||
|
<property file="nbproject/project.properties"/>
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
|
||||||
|
<available file="${manifest.file}" property="manifest.available"/>
|
||||||
|
<condition property="manifest.available+main.class">
|
||||||
|
<and>
|
||||||
|
<isset property="manifest.available"/>
|
||||||
|
<isset property="main.class"/>
|
||||||
|
<not>
|
||||||
|
<equals arg1="${main.class}" arg2="" trim="true"/>
|
||||||
|
</not>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<condition property="manifest.available+main.class+mkdist.available">
|
||||||
|
<and>
|
||||||
|
<istrue value="${manifest.available+main.class}"/>
|
||||||
|
<isset property="libs.CopyLibs.classpath"/>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<condition property="have.tests">
|
||||||
|
<or>
|
||||||
|
<available file="${test.test.dir}"/>
|
||||||
|
</or>
|
||||||
|
</condition>
|
||||||
|
<condition property="have.sources">
|
||||||
|
<or>
|
||||||
|
<available file="${src.src.dir}"/>
|
||||||
|
</or>
|
||||||
|
</condition>
|
||||||
|
<condition property="netbeans.home+have.tests">
|
||||||
|
<and>
|
||||||
|
<isset property="netbeans.home"/>
|
||||||
|
<isset property="have.tests"/>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<condition property="no.javadoc.preview">
|
||||||
|
<and>
|
||||||
|
<isset property="javadoc.preview"/>
|
||||||
|
<isfalse value="${javadoc.preview}"/>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<property name="run.jvmargs" value=""/>
|
||||||
|
<property name="javac.compilerargs" value=""/>
|
||||||
|
<property name="work.dir" value="${basedir}"/>
|
||||||
|
<condition property="no.deps">
|
||||||
|
<and>
|
||||||
|
<istrue value="${no.dependencies}"/>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<property name="javac.debug" value="true"/>
|
||||||
|
<property name="javadoc.preview" value="true"/>
|
||||||
|
<property name="application.args" value=""/>
|
||||||
|
<property name="source.encoding" value="${file.encoding}"/>
|
||||||
|
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
|
||||||
|
<and>
|
||||||
|
<isset property="javadoc.encoding"/>
|
||||||
|
<not>
|
||||||
|
<equals arg1="${javadoc.encoding}" arg2=""/>
|
||||||
|
</not>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
<property name="javadoc.encoding.used" value="${source.encoding}"/>
|
||||||
|
<property name="includes" value="**"/>
|
||||||
|
<property name="excludes" value=""/>
|
||||||
|
<property name="do.depend" value="false"/>
|
||||||
|
<condition property="do.depend.true">
|
||||||
|
<istrue value="${do.depend}"/>
|
||||||
|
</condition>
|
||||||
|
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
|
||||||
|
<and>
|
||||||
|
<isset property="jaxws.endorsed.dir"/>
|
||||||
|
<available file="nbproject/jaxws-build.xml"/>
|
||||||
|
</and>
|
||||||
|
</condition>
|
||||||
|
</target>
|
||||||
|
<target name="-post-init">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
|
||||||
|
<fail unless="src.src.dir">Must set src.src.dir</fail>
|
||||||
|
<fail unless="test.test.dir">Must set test.test.dir</fail>
|
||||||
|
<fail unless="build.dir">Must set build.dir</fail>
|
||||||
|
<fail unless="dist.dir">Must set dist.dir</fail>
|
||||||
|
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
|
||||||
|
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
|
||||||
|
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
|
||||||
|
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
|
||||||
|
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
|
||||||
|
<fail unless="dist.jar">Must set dist.jar</fail>
|
||||||
|
</target>
|
||||||
|
<target name="-init-macrodef-property">
|
||||||
|
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
|
<attribute name="name"/>
|
||||||
|
<attribute name="value"/>
|
||||||
|
<sequential>
|
||||||
|
<property name="@{name}" value="${@{value}}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target name="-init-macrodef-javac">
|
||||||
|
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<attribute default="${src.src.dir}" name="srcdir"/>
|
||||||
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
|
<attribute default="${javac.classpath}" name="classpath"/>
|
||||||
|
<attribute default="${includes}" name="includes"/>
|
||||||
|
<attribute default="${excludes}" name="excludes"/>
|
||||||
|
<attribute default="${javac.debug}" name="debug"/>
|
||||||
|
<attribute default="${empty.dir}" name="sourcepath"/>
|
||||||
|
<attribute default="${empty.dir}" name="gensrcdir"/>
|
||||||
|
<element name="customize" optional="true"/>
|
||||||
|
<sequential>
|
||||||
|
<property location="${build.dir}/empty" name="empty.dir"/>
|
||||||
|
<mkdir dir="${empty.dir}"/>
|
||||||
|
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
|
||||||
|
<src>
|
||||||
|
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
|
||||||
|
<include name="*"/>
|
||||||
|
</dirset>
|
||||||
|
</src>
|
||||||
|
<classpath>
|
||||||
|
<path path="@{classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
|
||||||
|
<customize/>
|
||||||
|
</javac>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<attribute default="${src.src.dir}" name="srcdir"/>
|
||||||
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
|
<attribute default="${javac.classpath}" name="classpath"/>
|
||||||
|
<sequential>
|
||||||
|
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
|
||||||
|
<classpath>
|
||||||
|
<path path="@{classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
</depend>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||||
|
<sequential>
|
||||||
|
<fail unless="javac.includes">Must set javac.includes</fail>
|
||||||
|
<pathconvert pathsep="," property="javac.includes.binary">
|
||||||
|
<path>
|
||||||
|
<filelist dir="@{destdir}" files="${javac.includes}"/>
|
||||||
|
</path>
|
||||||
|
<globmapper from="*.java" to="*.class"/>
|
||||||
|
</pathconvert>
|
||||||
|
<delete>
|
||||||
|
<files includes="${javac.includes.binary}"/>
|
||||||
|
</delete>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target name="-init-macrodef-junit">
|
||||||
|
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<attribute default="${includes}" name="includes"/>
|
||||||
|
<attribute default="${excludes}" name="excludes"/>
|
||||||
|
<attribute default="**" name="testincludes"/>
|
||||||
|
<sequential>
|
||||||
|
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
|
||||||
|
<batchtest todir="${build.test.results.dir}">
|
||||||
|
<fileset dir="${test.test.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
|
||||||
|
<filename name="@{testincludes}"/>
|
||||||
|
</fileset>
|
||||||
|
</batchtest>
|
||||||
|
<classpath>
|
||||||
|
<path path="${run.test.classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
<syspropertyset>
|
||||||
|
<propertyref prefix="test-sys-prop."/>
|
||||||
|
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||||
|
</syspropertyset>
|
||||||
|
<formatter type="brief" usefile="false"/>
|
||||||
|
<formatter type="xml"/>
|
||||||
|
<jvmarg line="${run.jvmargs}"/>
|
||||||
|
</junit>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
|
||||||
|
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
|
<attribute default="${main.class}" name="name"/>
|
||||||
|
<attribute default="${debug.classpath}" name="classpath"/>
|
||||||
|
<attribute default="" name="stopclassname"/>
|
||||||
|
<sequential>
|
||||||
|
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
|
||||||
|
<classpath>
|
||||||
|
<path path="@{classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
</nbjpdastart>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
|
<attribute default="${build.classes.dir}" name="dir"/>
|
||||||
|
<sequential>
|
||||||
|
<nbjpdareload>
|
||||||
|
<fileset dir="@{dir}" includes="${fix.classes}">
|
||||||
|
<include name="${fix.includes}*.class"/>
|
||||||
|
</fileset>
|
||||||
|
</nbjpdareload>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target name="-init-debug-args">
|
||||||
|
<property name="version-output" value="java version "${ant.java.version}"/>
|
||||||
|
<condition property="have-jdk-older-than-1.4">
|
||||||
|
<or>
|
||||||
|
<contains string="${version-output}" substring="java version "1.0"/>
|
||||||
|
<contains string="${version-output}" substring="java version "1.1"/>
|
||||||
|
<contains string="${version-output}" substring="java version "1.2"/>
|
||||||
|
<contains string="${version-output}" substring="java version "1.3"/>
|
||||||
|
</or>
|
||||||
|
</condition>
|
||||||
|
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
|
||||||
|
<istrue value="${have-jdk-older-than-1.4}"/>
|
||||||
|
</condition>
|
||||||
|
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
|
||||||
|
<os family="windows"/>
|
||||||
|
</condition>
|
||||||
|
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
|
||||||
|
<isset property="debug.transport"/>
|
||||||
|
</condition>
|
||||||
|
</target>
|
||||||
|
<target depends="-init-debug-args" name="-init-macrodef-debug">
|
||||||
|
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<attribute default="${main.class}" name="classname"/>
|
||||||
|
<attribute default="${debug.classpath}" name="classpath"/>
|
||||||
|
<element name="customize" optional="true"/>
|
||||||
|
<sequential>
|
||||||
|
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||||
|
<jvmarg line="${debug-args-line}"/>
|
||||||
|
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||||
|
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||||
|
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||||
|
<jvmarg line="${run.jvmargs}"/>
|
||||||
|
<classpath>
|
||||||
|
<path path="@{classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
<syspropertyset>
|
||||||
|
<propertyref prefix="run-sys-prop."/>
|
||||||
|
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||||
|
</syspropertyset>
|
||||||
|
<customize/>
|
||||||
|
</java>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target name="-init-macrodef-java">
|
||||||
|
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
|
<attribute default="${main.class}" name="classname"/>
|
||||||
|
<attribute default="${run.classpath}" name="classpath"/>
|
||||||
|
<element name="customize" optional="true"/>
|
||||||
|
<sequential>
|
||||||
|
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||||
|
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||||
|
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||||
|
<jvmarg line="${run.jvmargs}"/>
|
||||||
|
<classpath>
|
||||||
|
<path path="@{classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
<syspropertyset>
|
||||||
|
<propertyref prefix="run-sys-prop."/>
|
||||||
|
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||||
|
</syspropertyset>
|
||||||
|
<customize/>
|
||||||
|
</java>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
</target>
|
||||||
|
<target name="-init-presetdef-jar">
|
||||||
|
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
|
<jar compress="${jar.compress}" jarfile="${dist.jar}">
|
||||||
|
<j2seproject1:fileset dir="${build.classes.dir}"/>
|
||||||
|
</jar>
|
||||||
|
</presetdef>
|
||||||
|
</target>
|
||||||
|
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
|
||||||
|
<!--
|
||||||
|
===================
|
||||||
|
COMPILATION SECTION
|
||||||
|
===================
|
||||||
|
-->
|
||||||
|
<target depends="init" name="deps-jar" unless="no.deps">
|
||||||
|
<ant antfile="${project.Mage}/build.xml" inheritall="false" target="jar"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
|
||||||
|
<target depends="init" name="-check-automatic-build">
|
||||||
|
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
|
||||||
|
<antcall target="clean"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-jar" name="-pre-pre-compile">
|
||||||
|
<mkdir dir="${build.classes.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target name="-pre-compile">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target if="do.depend.true" name="-compile-depend">
|
||||||
|
<pathconvert property="build.generated.subdirs">
|
||||||
|
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||||
|
<include name="*"/>
|
||||||
|
</dirset>
|
||||||
|
</pathconvert>
|
||||||
|
<j2seproject3:depend srcdir="${src.src.dir}:${build.generated.subdirs}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
|
||||||
|
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
||||||
|
<copy todir="${build.classes.dir}">
|
||||||
|
<fileset dir="${src.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="-post-compile">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
|
||||||
|
<target name="-pre-compile-single">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
||||||
|
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||||
|
<j2seproject3:force-recompile/>
|
||||||
|
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.src.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target name="-post-compile-single">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
|
||||||
|
<!--
|
||||||
|
====================
|
||||||
|
JAR BUILDING SECTION
|
||||||
|
====================
|
||||||
|
-->
|
||||||
|
<target depends="init" name="-pre-pre-jar">
|
||||||
|
<dirname file="${dist.jar}" property="dist.jar.dir"/>
|
||||||
|
<mkdir dir="${dist.jar.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target name="-pre-jar">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
|
||||||
|
<j2seproject1:jar/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
|
||||||
|
<j2seproject1:jar manifest="${manifest.file}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
|
||||||
|
<j2seproject1:jar manifest="${manifest.file}">
|
||||||
|
<j2seproject1:manifest>
|
||||||
|
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
|
||||||
|
</j2seproject1:manifest>
|
||||||
|
</j2seproject1:jar>
|
||||||
|
<echo>To run this application from the command line without Ant, try:</echo>
|
||||||
|
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||||
|
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||||
|
<pathconvert property="run.classpath.with.dist.jar">
|
||||||
|
<path path="${run.classpath}"/>
|
||||||
|
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
|
||||||
|
</pathconvert>
|
||||||
|
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
|
||||||
|
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||||
|
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||||
|
<path path="${run.classpath}"/>
|
||||||
|
<map from="${build.classes.dir.resolved}" to=""/>
|
||||||
|
</pathconvert>
|
||||||
|
<pathconvert pathsep=" " property="jar.classpath">
|
||||||
|
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||||
|
<chainedmapper>
|
||||||
|
<flattenmapper/>
|
||||||
|
<globmapper from="*" to="lib/*"/>
|
||||||
|
</chainedmapper>
|
||||||
|
</pathconvert>
|
||||||
|
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||||
|
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class" value="${main.class}"/>
|
||||||
|
<attribute name="Class-Path" value="${jar.classpath}"/>
|
||||||
|
</manifest>
|
||||||
|
</copylibs>
|
||||||
|
<echo>To run this application from the command line without Ant, try:</echo>
|
||||||
|
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||||
|
<echo>java -jar "${dist.jar.resolved}"</echo>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
|
||||||
|
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||||
|
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||||
|
<path path="${run.classpath}"/>
|
||||||
|
<map from="${build.classes.dir.resolved}" to=""/>
|
||||||
|
</pathconvert>
|
||||||
|
<pathconvert pathsep=" " property="jar.classpath">
|
||||||
|
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||||
|
<chainedmapper>
|
||||||
|
<flattenmapper/>
|
||||||
|
<globmapper from="*" to="lib/*"/>
|
||||||
|
</chainedmapper>
|
||||||
|
</pathconvert>
|
||||||
|
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||||
|
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</copylibs>
|
||||||
|
</target>
|
||||||
|
<target name="-post-jar">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
|
||||||
|
<!--
|
||||||
|
=================
|
||||||
|
EXECUTION SECTION
|
||||||
|
=================
|
||||||
|
-->
|
||||||
|
<target depends="init,compile" description="Run a main class." name="run">
|
||||||
|
<j2seproject1:java>
|
||||||
|
<customize>
|
||||||
|
<arg line="${application.args}"/>
|
||||||
|
</customize>
|
||||||
|
</j2seproject1:java>
|
||||||
|
</target>
|
||||||
|
<target name="-do-not-recompile">
|
||||||
|
<property name="javac.includes.binary" value=""/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-single" name="run-single">
|
||||||
|
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||||
|
<j2seproject1:java classname="${run.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
|
||||||
|
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||||
|
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
|
||||||
|
</target>
|
||||||
|
<!--
|
||||||
|
=================
|
||||||
|
DEBUGGING SECTION
|
||||||
|
=================
|
||||||
|
-->
|
||||||
|
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
|
||||||
|
<j2seproject1:nbjpdastart name="${debug.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
|
||||||
|
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile" name="-debug-start-debuggee">
|
||||||
|
<j2seproject3:debug>
|
||||||
|
<customize>
|
||||||
|
<arg line="${application.args}"/>
|
||||||
|
</customize>
|
||||||
|
</j2seproject3:debug>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
|
||||||
|
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
|
||||||
|
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
|
||||||
|
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
|
||||||
|
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||||
|
<j2seproject3:debug classname="${debug.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
|
||||||
|
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
|
||||||
|
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||||
|
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
|
||||||
|
<target depends="init" name="-pre-debug-fix">
|
||||||
|
<fail unless="fix.includes">Must set fix.includes</fail>
|
||||||
|
<property name="javac.includes" value="${fix.includes}.java"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
|
||||||
|
<j2seproject1:nbjpdareload/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
|
||||||
|
<!--
|
||||||
|
===============
|
||||||
|
JAVADOC SECTION
|
||||||
|
===============
|
||||||
|
-->
|
||||||
|
<target depends="init" name="-javadoc-build">
|
||||||
|
<mkdir dir="${dist.javadoc.dir}"/>
|
||||||
|
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
|
||||||
|
<classpath>
|
||||||
|
<path path="${javac.classpath}"/>
|
||||||
|
</classpath>
|
||||||
|
<fileset dir="${src.src.dir}" excludes="${excludes}" includes="${includes}">
|
||||||
|
<filename name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
|
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||||
|
<include name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
|
</javadoc>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
|
||||||
|
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
|
||||||
|
<!--
|
||||||
|
=========================
|
||||||
|
JUNIT COMPILATION SECTION
|
||||||
|
=========================
|
||||||
|
-->
|
||||||
|
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
|
||||||
|
<mkdir dir="${build.test.classes.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target name="-pre-compile-test">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target if="do.depend.true" name="-compile-test-depend">
|
||||||
|
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.test.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
|
||||||
|
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.test.dir}"/>
|
||||||
|
<copy todir="${build.test.classes.dir}">
|
||||||
|
<fileset dir="${test.test.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="-post-compile-test">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
|
||||||
|
<target name="-pre-compile-test-single">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
|
||||||
|
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||||
|
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
|
||||||
|
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.test.dir}" srcdir="${test.test.dir}"/>
|
||||||
|
<copy todir="${build.test.classes.dir}">
|
||||||
|
<fileset dir="${test.test.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="-post-compile-test-single">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
|
||||||
|
<!--
|
||||||
|
=======================
|
||||||
|
JUNIT EXECUTION SECTION
|
||||||
|
=======================
|
||||||
|
-->
|
||||||
|
<target depends="init" if="have.tests" name="-pre-test-run">
|
||||||
|
<mkdir dir="${build.test.results.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
|
||||||
|
<j2seproject3:junit testincludes="**/*Test.java"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
||||||
|
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||||
|
</target>
|
||||||
|
<target depends="init" if="have.tests" name="test-report"/>
|
||||||
|
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
|
||||||
|
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
|
||||||
|
<target depends="init" if="have.tests" name="-pre-test-run-single">
|
||||||
|
<mkdir dir="${build.test.results.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
|
||||||
|
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
|
||||||
|
<j2seproject3:junit excludes="" includes="${test.includes}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
|
||||||
|
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
|
||||||
|
<!--
|
||||||
|
=======================
|
||||||
|
JUNIT DEBUGGING SECTION
|
||||||
|
=======================
|
||||||
|
-->
|
||||||
|
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
|
||||||
|
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
|
||||||
|
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
|
||||||
|
<delete file="${test.report.file}"/>
|
||||||
|
<mkdir dir="${build.test.results.dir}"/>
|
||||||
|
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
|
||||||
|
<customize>
|
||||||
|
<syspropertyset>
|
||||||
|
<propertyref prefix="test-sys-prop."/>
|
||||||
|
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||||
|
</syspropertyset>
|
||||||
|
<arg value="${test.class}"/>
|
||||||
|
<arg value="showoutput=true"/>
|
||||||
|
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
|
||||||
|
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
|
||||||
|
</customize>
|
||||||
|
</j2seproject3:debug>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
|
||||||
|
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
|
||||||
|
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
|
||||||
|
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
|
||||||
|
<!--
|
||||||
|
=========================
|
||||||
|
APPLET EXECUTION SECTION
|
||||||
|
=========================
|
||||||
|
-->
|
||||||
|
<target depends="init,compile-single" name="run-applet">
|
||||||
|
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||||
|
<j2seproject1:java classname="sun.applet.AppletViewer">
|
||||||
|
<customize>
|
||||||
|
<arg value="${applet.url}"/>
|
||||||
|
</customize>
|
||||||
|
</j2seproject1:java>
|
||||||
|
</target>
|
||||||
|
<!--
|
||||||
|
=========================
|
||||||
|
APPLET DEBUGGING SECTION
|
||||||
|
=========================
|
||||||
|
-->
|
||||||
|
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
|
||||||
|
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||||
|
<j2seproject3:debug classname="sun.applet.AppletViewer">
|
||||||
|
<customize>
|
||||||
|
<arg value="${applet.url}"/>
|
||||||
|
</customize>
|
||||||
|
</j2seproject3:debug>
|
||||||
|
</target>
|
||||||
|
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
|
||||||
|
<!--
|
||||||
|
===============
|
||||||
|
CLEANUP SECTION
|
||||||
|
===============
|
||||||
|
-->
|
||||||
|
<target depends="init" name="deps-clean" unless="no.deps">
|
||||||
|
<ant antfile="${project.Mage}/build.xml" inheritall="false" target="clean"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init" name="-do-clean">
|
||||||
|
<delete dir="${build.dir}"/>
|
||||||
|
<delete dir="${dist.dir}"/>
|
||||||
|
</target>
|
||||||
|
<target name="-post-clean">
|
||||||
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
|
</target>
|
||||||
|
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
|
||||||
|
</project>
|
8
Mage.Player.AI/nbproject/genfiles.properties
Normal file
8
Mage.Player.AI/nbproject/genfiles.properties
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
build.xml.data.CRC32=3dcf0fdd
|
||||||
|
build.xml.script.CRC32=b5a10489
|
||||||
|
build.xml.stylesheet.CRC32=958a1d3e@1.26.2.45
|
||||||
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||||
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||||
|
nbproject/build-impl.xml.data.CRC32=3dcf0fdd
|
||||||
|
nbproject/build-impl.xml.script.CRC32=8d227e35
|
||||||
|
nbproject/build-impl.xml.stylesheet.CRC32=5c621a33@1.26.2.45
|
3
Mage.Player.AI/nbproject/private/private.properties
Normal file
3
Mage.Player.AI/nbproject/private/private.properties
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
file.reference.Mage.AI-test=C:\\Projects\\Mage\\Mage.Player.AI\\test
|
||||||
|
jaxws.endorsed.dir=C:\\Program Files (x86)\\NetBeans 6.7.1\\java2\\modules\\ext\\jaxws21\\api:C:\\Program Files (x86)\\NetBeans 6.7.1\\ide11\\modules\\ext\\jaxb\\api
|
||||||
|
user.properties.file=C:\\Users\\Bill\\.netbeans\\6.7\\build.properties
|
4
Mage.Player.AI/nbproject/private/private.xml
Normal file
4
Mage.Player.AI/nbproject/private/private.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||||
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
||||||
|
</project-private>
|
70
Mage.Player.AI/nbproject/project.properties
Normal file
70
Mage.Player.AI/nbproject/project.properties
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
application.title=Mage.Player.AI
|
||||||
|
application.vendor=BetaSteward_at_googlemail.com
|
||||||
|
build.classes.dir=${build.dir}/classes
|
||||||
|
build.classes.excludes=**/*.java,**/*.form
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
build.dir=build
|
||||||
|
build.generated.dir=${build.dir}/generated
|
||||||
|
build.generated.sources.dir=${build.dir}/generated-sources
|
||||||
|
# Only compile against the classpath explicitly listed here:
|
||||||
|
build.sysclasspath=ignore
|
||||||
|
build.test.classes.dir=${build.dir}/test/classes
|
||||||
|
build.test.results.dir=${build.dir}/test/results
|
||||||
|
# Uncomment to specify the preferred debugger connection transport:
|
||||||
|
#debug.transport=dt_socket
|
||||||
|
debug.classpath=\
|
||||||
|
${run.classpath}
|
||||||
|
debug.test.classpath=\
|
||||||
|
${run.test.classpath}
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
dist.dir=dist
|
||||||
|
dist.jar=${dist.dir}/Mage.Player.AI.jar
|
||||||
|
dist.javadoc.dir=${dist.dir}/javadoc
|
||||||
|
excludes=
|
||||||
|
file.reference.Mage.AI-src=src
|
||||||
|
file.reference.Mage.AI-test=test
|
||||||
|
includes=**
|
||||||
|
jar.compress=false
|
||||||
|
javac.classpath=\
|
||||||
|
${reference.Mage.jar}
|
||||||
|
# Space-separated list of extra javac options
|
||||||
|
javac.compilerargs=
|
||||||
|
javac.deprecation=false
|
||||||
|
javac.source=1.6
|
||||||
|
javac.target=1.6
|
||||||
|
javac.test.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}:\
|
||||||
|
${libs.junit.classpath}:\
|
||||||
|
${libs.junit_4.classpath}
|
||||||
|
javadoc.additionalparam=
|
||||||
|
javadoc.author=false
|
||||||
|
javadoc.encoding=${source.encoding}
|
||||||
|
javadoc.noindex=false
|
||||||
|
javadoc.nonavbar=false
|
||||||
|
javadoc.notree=false
|
||||||
|
javadoc.private=false
|
||||||
|
javadoc.splitindex=true
|
||||||
|
javadoc.use=true
|
||||||
|
javadoc.version=false
|
||||||
|
javadoc.windowtitle=
|
||||||
|
main.class=
|
||||||
|
manifest.file=manifest.mf
|
||||||
|
meta.inf.dir=${src.dir}/META-INF
|
||||||
|
platform.active=default_platform
|
||||||
|
project.license=bsd
|
||||||
|
project.Mage=../Mage
|
||||||
|
reference.Mage.jar=${project.Mage}/dist/Mage.jar
|
||||||
|
run.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}
|
||||||
|
# Space-separated list of JVM arguments used when running the project
|
||||||
|
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
|
||||||
|
# or test-sys-prop.name=value to set system properties for unit tests):
|
||||||
|
run.jvmargs=
|
||||||
|
run.test.classpath=\
|
||||||
|
${javac.test.classpath}:\
|
||||||
|
${build.test.classes.dir}
|
||||||
|
source.encoding=UTF-8
|
||||||
|
src.src.dir=src
|
||||||
|
test.test.dir=test
|
25
Mage.Player.AI/nbproject/project.xml
Normal file
25
Mage.Player.AI/nbproject/project.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.java.j2seproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<name>Mage.Player.AI</name>
|
||||||
|
<source-roots>
|
||||||
|
<root id="src.src.dir"/>
|
||||||
|
</source-roots>
|
||||||
|
<test-roots>
|
||||||
|
<root id="test.test.dir"/>
|
||||||
|
</test-roots>
|
||||||
|
</data>
|
||||||
|
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
|
||||||
|
<reference>
|
||||||
|
<foreign-project>Mage</foreign-project>
|
||||||
|
<artifact-type>jar</artifact-type>
|
||||||
|
<script>build.xml</script>
|
||||||
|
<target>jar</target>
|
||||||
|
<clean-target>clean</clean-target>
|
||||||
|
<id>jar</id>
|
||||||
|
</reference>
|
||||||
|
</references>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
52
Mage.Player.AI/src/mage/player/ai/Attackers.java
Normal file
52
Mage.Player.AI/src/mage/player/ai/Attackers.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class Attackers extends TreeMap<Integer, List<Permanent>> {
|
||||||
|
|
||||||
|
public List<Permanent> getAttackers() {
|
||||||
|
List<Permanent> attackers = new ArrayList<Permanent>();
|
||||||
|
for (List<Permanent> l: this.values()) {
|
||||||
|
for (Permanent permanent: l) {
|
||||||
|
attackers.add(permanent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attackers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
764
Mage.Player.AI/src/mage/player/ai/ComputerPlayer.java
Normal file
764
Mage.Player.AI/src/mage/player/ai/ComputerPlayer.java
Normal file
|
@ -0,0 +1,764 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Outcome;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.Mana;
|
||||||
|
import mage.abilities.ActivatedAbility;
|
||||||
|
import mage.abilities.TriggeredAbilities;
|
||||||
|
import mage.abilities.TriggeredAbility;
|
||||||
|
import mage.abilities.costs.mana.ColoredManaCost;
|
||||||
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
|
import mage.abilities.costs.mana.HybridManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
|
import mage.abilities.costs.mana.MonoHybridManaCost;
|
||||||
|
import mage.abilities.costs.mana.VariableManaCost;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
|
import mage.abilities.effects.ReplacementEffect;
|
||||||
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
|
import mage.abilities.keyword.FirstStrikeAbility;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.abilities.mana.ManaAbility;
|
||||||
|
import mage.abilities.mana.ManaOptions;
|
||||||
|
import mage.player.ai.simulators.CombatGroupSimulator;
|
||||||
|
import mage.player.ai.simulators.CombatSimulator;
|
||||||
|
import mage.player.ai.simulators.CreatureSimulator;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.Cards;
|
||||||
|
import mage.choices.Choice;
|
||||||
|
import mage.filter.common.FilterCreatureForAttack;
|
||||||
|
import mage.filter.common.FilterCreatureForCombat;
|
||||||
|
import mage.filter.common.FilterLandCard;
|
||||||
|
import mage.filter.common.FilterNonlandCard;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.GameState;
|
||||||
|
import mage.game.combat.CombatGroup;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.players.PlayerImpl;
|
||||||
|
import mage.target.Target;
|
||||||
|
import mage.target.TargetCard;
|
||||||
|
import mage.target.TargetPermanent;
|
||||||
|
import mage.target.TargetPlayer;
|
||||||
|
import mage.target.common.TargetDiscard;
|
||||||
|
import mage.util.Copier;
|
||||||
|
import mage.util.Logging;
|
||||||
|
import mage.util.TreeNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* only suitable for two player games
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
|
|
||||||
|
private final static Logger logger = Logging.getLogger(ComputerPlayer.class.getName());
|
||||||
|
private boolean abort = false;
|
||||||
|
private Map<Mana, Card> unplayable = new TreeMap<Mana, Card>();
|
||||||
|
private List<Card> playableNonInstant = new ArrayList<Card>();
|
||||||
|
private List<Card> playableInstant = new ArrayList<Card>();
|
||||||
|
private List<ActivatedAbility> playableAbilities = new ArrayList<ActivatedAbility>();
|
||||||
|
|
||||||
|
public ComputerPlayer(String name) {
|
||||||
|
super(name);
|
||||||
|
human = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean chooseMulligan(Game game) {
|
||||||
|
logger.fine("chooseMulligan");
|
||||||
|
if (hand.size() < 6)
|
||||||
|
return false;
|
||||||
|
List<Card> lands = hand.getCards(new FilterLandCard());
|
||||||
|
if (lands.size() < 2 || lands.size() > hand.size() - 2)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean chooseTarget(Outcome outcome, Target target, Game game) {
|
||||||
|
logger.fine("chooseTarget: " + outcome.toString() + ":" + target.toString());
|
||||||
|
UUID opponentId = game.getOpponents(playerId).get(0);
|
||||||
|
if (target instanceof TargetPlayer) {
|
||||||
|
if (outcome.isGood()) {
|
||||||
|
if (target.canTarget(playerId, game)) {
|
||||||
|
target.addTarget(playerId, game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (target.canTarget(playerId, game)) {
|
||||||
|
target.addTarget(opponentId, game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target instanceof TargetDiscard) {
|
||||||
|
findPlayables(game);
|
||||||
|
if (unplayable.size() > 0) {
|
||||||
|
for (int i = unplayable.size() - 1; i >= 0; i--) {
|
||||||
|
if (target.canTarget(unplayable.values().toArray(new Card[0])[i].getId(), game)) {
|
||||||
|
target.addTarget(unplayable.values().toArray(new Card[0])[i].getId(), game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hand.size() > 0) {
|
||||||
|
if (target.canTarget(hand.keySet().toArray(new UUID[0])[0], game)) {
|
||||||
|
target.addTarget(hand.keySet().toArray(new UUID[0])[0], game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target instanceof TargetPermanent) {
|
||||||
|
List<Permanent> targets;
|
||||||
|
if (outcome.isGood()) {
|
||||||
|
targets = threats(playerId, (TargetPermanent) target, game);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
targets = threats(opponentId, (TargetPermanent) target, game);
|
||||||
|
}
|
||||||
|
for (Permanent permanent: targets) {
|
||||||
|
if (target.canTarget(permanent.getId(), game)) {
|
||||||
|
target.addTarget(permanent.getId(), game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void priority(Game game) {
|
||||||
|
logger.fine("priority");
|
||||||
|
if (game.getActivePlayerId().equals(playerId)) {
|
||||||
|
if (game.isMainPhase() && game.getStack().isEmpty()) {
|
||||||
|
playLand(game);
|
||||||
|
}
|
||||||
|
switch (game.getTurn().getStep()) {
|
||||||
|
case UPKEEP:
|
||||||
|
findPlayables(game);
|
||||||
|
break;
|
||||||
|
case DRAW:
|
||||||
|
logState(game);
|
||||||
|
case DECLARE_BLOCKERS:
|
||||||
|
playRemoval(game.getCombat().getAttackers(), game);
|
||||||
|
case PRECOMBAT_MAIN:
|
||||||
|
findPlayables(game);
|
||||||
|
if (playableAbilities.size() > 0) {
|
||||||
|
for (ActivatedAbility ability: playableAbilities) {
|
||||||
|
if (ability.canActivate(playerId, game)) {
|
||||||
|
if (ability.getEffects().hasOutcome(Outcome.PutLandInPlay)) {
|
||||||
|
if (this.activateAbility(ability, game))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case POSTCOMBAT_MAIN:
|
||||||
|
findPlayables(game);
|
||||||
|
if (game.getStack().isEmpty()) {
|
||||||
|
if (playableNonInstant.size() > 0) {
|
||||||
|
for (Card card: playableNonInstant) {
|
||||||
|
if (card.getSpellAbility().canActivate(playerId, game)) {
|
||||||
|
if (this.activateAbility(card.getSpellAbility(), game))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (playableAbilities.size() > 0) {
|
||||||
|
for (ActivatedAbility ability: playableAbilities) {
|
||||||
|
if (ability.canActivate(playerId, game)) {
|
||||||
|
if (this.activateAbility(ability, game))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//respond to opponent events
|
||||||
|
}
|
||||||
|
this.passed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playLand(Game game) {
|
||||||
|
logger.fine("playLand");
|
||||||
|
List<Card> lands = hand.getCards(new FilterLandCard());
|
||||||
|
while (lands.size() > 0 && this.landsPlayed < this.landsPerTurn) {
|
||||||
|
if (lands.size() == 1)
|
||||||
|
this.playLand(lands.get(0), game);
|
||||||
|
else {
|
||||||
|
playALand(lands, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playALand(List<Card> lands, Game game) {
|
||||||
|
logger.fine("playALand");
|
||||||
|
//play a land that will allow us to play an unplayable
|
||||||
|
for (Mana mana: unplayable.keySet()) {
|
||||||
|
for (Card card: lands) {
|
||||||
|
for (ManaAbility ability: card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (ability.getNetMana().enough(mana)) {
|
||||||
|
this.playLand(card, game);
|
||||||
|
lands.remove(card);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//play a land that will get us closer to playing an unplayable
|
||||||
|
for (Mana mana: unplayable.keySet()) {
|
||||||
|
for (Card card: lands) {
|
||||||
|
for (ManaAbility ability: card.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (mana.contains(ability.getNetMana())) {
|
||||||
|
this.playLand(card, game);
|
||||||
|
lands.remove(card);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//play first available land
|
||||||
|
this.playLand(lands.get(0), game);
|
||||||
|
lands.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findPlayables(Game game) {
|
||||||
|
playableInstant.clear();
|
||||||
|
playableNonInstant.clear();
|
||||||
|
unplayable.clear();
|
||||||
|
playableAbilities.clear();
|
||||||
|
List<Card> nonLands = hand.getCards(new FilterNonlandCard());
|
||||||
|
ManaOptions available = getManaAvailable(game);
|
||||||
|
available.addMana(manaPool.getMana());
|
||||||
|
|
||||||
|
for (Card card: nonLands) {
|
||||||
|
ManaOptions options = card.getManaCost().getOptions();
|
||||||
|
if (card.getManaCost().getVariableCosts().size() > 0) {
|
||||||
|
//don't use variable mana costs unless there is at least 3 extra mana for X
|
||||||
|
for (Mana option: options) {
|
||||||
|
option.add(Mana.ColorlessMana(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Mana mana: options) {
|
||||||
|
for (Mana avail: available) {
|
||||||
|
if (mana.enough(avail)) {
|
||||||
|
if (card.getCardType().contains(CardType.INSTANT))
|
||||||
|
playableInstant.add(card);
|
||||||
|
else
|
||||||
|
playableNonInstant.add(card);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!playableInstant.contains(card) && !playableNonInstant.contains(card))
|
||||||
|
unplayable.put(mana.needed(avail), card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(playerId)) {
|
||||||
|
for (ActivatedAbility ability: permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (!(ability instanceof ManaAbility) && ability.canActivate(playerId, game)) {
|
||||||
|
ManaOptions abilityOptions = ability.getManaCosts().getOptions();
|
||||||
|
if (ability.getManaCosts().getVariableCosts().size() > 0) {
|
||||||
|
//don't use variable mana costs unless there is at least 3 extra mana for X
|
||||||
|
for (Mana option: abilityOptions) {
|
||||||
|
option.add(Mana.ColorlessMana(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (abilityOptions.size() == 0) {
|
||||||
|
playableAbilities.add(ability);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (Mana mana: abilityOptions) {
|
||||||
|
for (Mana avail: available) {
|
||||||
|
if (mana.enough(avail)) {
|
||||||
|
playableAbilities.add(ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.fine("findPlayables: " + playableInstant.toString() + "---" + playableNonInstant.toString() + "---" + playableAbilities.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ManaOptions getManaAvailable(Game game) {
|
||||||
|
logger.fine("getManaAvailable");
|
||||||
|
List<Permanent> manaPerms = this.getAvailableManaProducers(game);
|
||||||
|
|
||||||
|
ManaOptions available = new ManaOptions();
|
||||||
|
for (Permanent perm: manaPerms) {
|
||||||
|
available.addMana(perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD));
|
||||||
|
}
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playMana(ManaCost unpaid, Game game) {
|
||||||
|
logger.fine("playMana");
|
||||||
|
ManaCost cost;
|
||||||
|
List<Permanent> producers;
|
||||||
|
if (unpaid instanceof ManaCosts) {
|
||||||
|
cost = ((ManaCosts)unpaid).get(0);
|
||||||
|
producers = getSortedProducers((ManaCosts)unpaid, game);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cost = unpaid;
|
||||||
|
producers = this.getAvailableManaProducers(game);
|
||||||
|
}
|
||||||
|
for (Permanent perm: producers) {
|
||||||
|
// pay all colored costs first
|
||||||
|
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (cost instanceof ColoredManaCost) {
|
||||||
|
if (cost.testPay(ability.getNetMana())) {
|
||||||
|
if (activateAbility(ability, game))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then pay hybrid
|
||||||
|
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (cost instanceof HybridManaCost) {
|
||||||
|
if (cost.testPay(ability.getNetMana())) {
|
||||||
|
if (activateAbility(ability, game))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// then pay mono hybrid
|
||||||
|
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (cost instanceof MonoHybridManaCost) {
|
||||||
|
if (cost.testPay(ability.getNetMana())) {
|
||||||
|
if (activateAbility(ability, game))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finally pay generic
|
||||||
|
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (cost instanceof GenericManaCost) {
|
||||||
|
if (cost.testPay(ability.getNetMana())) {
|
||||||
|
if (activateAbility(ability, game))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Permanent> getSortedProducers(ManaCosts unpaid, Game game) {
|
||||||
|
List<Permanent> unsorted = this.getAvailableManaProducers(game);
|
||||||
|
Map<Permanent, Integer> scored = new HashMap<Permanent, Integer>();
|
||||||
|
for (Permanent permanent: unsorted) {
|
||||||
|
int score = 0;
|
||||||
|
for (ManaCost cost: unpaid) {
|
||||||
|
for (ManaAbility ability: permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (cost.testPay(ability.getNetMana())) {
|
||||||
|
score++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scored.put(permanent, score);
|
||||||
|
}
|
||||||
|
return sortByValue(scored);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Permanent> sortByValue(Map<Permanent, Integer> map) {
|
||||||
|
List<Entry<Permanent, Integer>> list = new LinkedList<Entry<Permanent, Integer>>(map.entrySet());
|
||||||
|
Collections.sort(list, new Comparator<Entry<Permanent, Integer>>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Entry<Permanent, Integer> o1, Entry<Permanent, Integer> o2) {
|
||||||
|
return (o1.getValue().compareTo(o2.getValue()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<Permanent> result = new ArrayList<Permanent>();
|
||||||
|
for (Iterator it = list.iterator(); it.hasNext();) {
|
||||||
|
Entry<Permanent, Integer> entry = (Entry<Permanent, Integer>)it.next();
|
||||||
|
result.add(entry.getKey());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playXMana(VariableManaCost cost, Game game) {
|
||||||
|
logger.fine("playXMana");
|
||||||
|
//put everything into X
|
||||||
|
for (Permanent perm: this.getAvailableManaProducers(game)) {
|
||||||
|
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (activateAbility(ability, game))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cost.setPaid();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void abort() {
|
||||||
|
abort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean chooseUse(Outcome outcome, String message, Game game) {
|
||||||
|
logger.fine("chooseUse");
|
||||||
|
//TODO: improve this
|
||||||
|
return outcome.isGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
||||||
|
logger.fine("choose");
|
||||||
|
//TODO: improve this
|
||||||
|
choice.setChoice(choice.getChoices().get(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean searchCards(Cards cards, TargetCard target, Game game) {
|
||||||
|
logger.fine("searchCards");
|
||||||
|
//TODO: improve ths
|
||||||
|
//return first match
|
||||||
|
for (Card card: cards.getCards(target.getFilter())) {
|
||||||
|
target.addTarget(card.getId(), game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectAttackers(Game game) {
|
||||||
|
logger.fine("selectAttackers");
|
||||||
|
UUID opponentId = game.getOpponents(playerId).get(0);
|
||||||
|
Attackers attackers = getAvailableAttackers(game);
|
||||||
|
List<Permanent> blockers = getOpponentBlockers(opponentId, game);
|
||||||
|
List<Permanent> actualAttackers = new ArrayList<Permanent>();
|
||||||
|
if (blockers.isEmpty()) {
|
||||||
|
actualAttackers = attackers.getAttackers();
|
||||||
|
}
|
||||||
|
else if (attackers.size() - blockers.size() >= game.getPlayer(opponentId).getLife()) {
|
||||||
|
actualAttackers = attackers.getAttackers();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CombatSimulator combat = simulateAttack(attackers, blockers, opponentId, game);
|
||||||
|
if (combat.rating > 2) {
|
||||||
|
for (CombatGroupSimulator group: combat.groups) {
|
||||||
|
this.declareAttacker(group.attackers.get(0).id, group.defenderId, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Permanent attacker: actualAttackers) {
|
||||||
|
this.declareAttacker(attacker.getId(), opponentId, game);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectBlockers(Game game) {
|
||||||
|
logger.fine("selectBlockers");
|
||||||
|
|
||||||
|
List<Permanent> blockers = getAvailableBlockers(game);
|
||||||
|
|
||||||
|
CombatSimulator sim = simulateBlock(CombatSimulator.load(game), blockers, game);
|
||||||
|
|
||||||
|
List<CombatGroup> groups = game.getCombat().getGroups();
|
||||||
|
for (int i = 0; i< groups.size(); i++) {
|
||||||
|
for (CreatureSimulator creature: sim.groups.get(i).blockers) {
|
||||||
|
groups.get(i).addBlocker(creature.id, playerId, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int chooseEffect(List<ReplacementEffect> rEffects, Game game) {
|
||||||
|
logger.fine("chooseEffect");
|
||||||
|
//TODO: implement this
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TriggeredAbility chooseTriggeredAbility(TriggeredAbilities abilities, Game game) {
|
||||||
|
logger.fine("chooseTriggeredAbility");
|
||||||
|
//TODO: improve this
|
||||||
|
if (abilities.size() > 0)
|
||||||
|
return abilities.get(0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assignDamage(int damage, List<UUID> targets, UUID sourceId, Game game) {
|
||||||
|
logger.fine("assignDamage");
|
||||||
|
//TODO: improve this
|
||||||
|
game.getPermanent(targets.get(0)).damage(damage, sourceId, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAmount(int min, int max, String message, Game game) {
|
||||||
|
logger.fine("getAmount");
|
||||||
|
//TODO: improve this
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Permanent> getAvailableManaProducers(Game game) {
|
||||||
|
logger.fine("getAvailableManaProducers");
|
||||||
|
List<Permanent> result = new ArrayList<Permanent>();
|
||||||
|
for (Permanent permanent: game.getBattlefield().getActivePermanents(playerId)) {
|
||||||
|
for (ManaAbility ability: permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||||
|
if (ability.canActivate(playerId, game)) {
|
||||||
|
result.add(permanent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Attackers getAvailableAttackers(Game game) {
|
||||||
|
logger.fine("getAvailableAttackers");
|
||||||
|
FilterCreatureForAttack attackFilter = new FilterCreatureForAttack();
|
||||||
|
attackFilter.getControllerId().add(playerId);
|
||||||
|
Attackers attackers = new Attackers();
|
||||||
|
List<Permanent> creatures = game.getBattlefield().getActivePermanents(attackFilter);
|
||||||
|
for (Permanent creature: creatures) {
|
||||||
|
int potential = combatPotential(creature, game);
|
||||||
|
if (potential > 0) {
|
||||||
|
List<Permanent> l = attackers.get(potential);
|
||||||
|
if (l == null)
|
||||||
|
attackers.put(potential, l = new ArrayList<Permanent>());
|
||||||
|
l.add(creature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attackers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int combatPotential(Permanent creature, Game game) {
|
||||||
|
logger.fine("combatPotential");
|
||||||
|
if (!creature.canAttack(game))
|
||||||
|
return 0;
|
||||||
|
int potential = creature.getPower().getValue();
|
||||||
|
potential += creature.getAbilities().getEvasionAbilities().size();
|
||||||
|
potential += creature.getAbilities().getProtectionAbilities().size();
|
||||||
|
potential += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0;
|
||||||
|
potential += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0;
|
||||||
|
potential += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0;
|
||||||
|
return potential;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Permanent> getAvailableBlockers(Game game) {
|
||||||
|
logger.fine("getAvailableBlockers");
|
||||||
|
FilterCreatureForCombat blockFilter = new FilterCreatureForCombat();
|
||||||
|
blockFilter.getControllerId().add(playerId);
|
||||||
|
List<Permanent> blockers = game.getBattlefield().getActivePermanents(blockFilter);
|
||||||
|
return blockers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Permanent> getOpponentBlockers(UUID opponentId, Game game) {
|
||||||
|
logger.fine("getOpponentBlockers");
|
||||||
|
FilterCreatureForCombat blockFilter = new FilterCreatureForCombat();
|
||||||
|
blockFilter.getControllerId().add(opponentId);
|
||||||
|
List<Permanent> blockers = game.getBattlefield().getActivePermanents(blockFilter);
|
||||||
|
return blockers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CombatSimulator simulateAttack(Attackers attackers, List<Permanent> blockers, UUID opponentId, Game game) {
|
||||||
|
logger.fine("simulateAttack");
|
||||||
|
List<Permanent> attackersList = attackers.getAttackers();
|
||||||
|
CombatSimulator best = new CombatSimulator();
|
||||||
|
int bestResult = 0;
|
||||||
|
//use binary digits to calculate powerset of attackers
|
||||||
|
int powerElements = (int) Math.pow(2, attackersList.size());
|
||||||
|
for (int i = 1; i < powerElements; i++) {
|
||||||
|
String binary = Integer.toBinaryString(i);
|
||||||
|
while(binary.length() < attackersList.size()) {
|
||||||
|
binary = "0" + binary;
|
||||||
|
}
|
||||||
|
List<Permanent> trialAttackers = new ArrayList<Permanent>();
|
||||||
|
for (int j = 0; j < attackersList.size(); j++) {
|
||||||
|
if (binary.charAt(j) == '1')
|
||||||
|
trialAttackers.add(attackersList.get(j));
|
||||||
|
}
|
||||||
|
CombatSimulator combat = new CombatSimulator();
|
||||||
|
for (Permanent permanent: trialAttackers) {
|
||||||
|
combat.groups.add(new CombatGroupSimulator(opponentId, Arrays.asList(permanent.getId()), new ArrayList<UUID>(), game));
|
||||||
|
}
|
||||||
|
CombatSimulator test = simulateBlock(combat, blockers, game);
|
||||||
|
if (test.evaluate() > bestResult) {
|
||||||
|
best = test;
|
||||||
|
bestResult = test.evaluate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CombatSimulator simulateBlock(CombatSimulator combat, List<Permanent> blockers, Game game) {
|
||||||
|
logger.fine("simulateBlock");
|
||||||
|
|
||||||
|
TreeNode<CombatSimulator> simulations;
|
||||||
|
|
||||||
|
simulations = new TreeNode<CombatSimulator>(combat);
|
||||||
|
addBlockSimulations(blockers, simulations, game);
|
||||||
|
combat.simulate();
|
||||||
|
|
||||||
|
return getWorstSimulation(simulations);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addBlockSimulations(List<Permanent> blockers, TreeNode<CombatSimulator> node, Game game) {
|
||||||
|
int numGroups = node.getData().groups.size();
|
||||||
|
Copier<CombatSimulator> copier = new Copier<CombatSimulator>();
|
||||||
|
for (Permanent blocker: blockers) {
|
||||||
|
List<Permanent> subList = remove(blockers, blocker);
|
||||||
|
for (int i = 0; i < numGroups; i++) {
|
||||||
|
if (node.getData().groups.get(i).canBlock(blocker, game)) {
|
||||||
|
CombatSimulator combat = copier.copy(node.getData());
|
||||||
|
combat.groups.get(i).blockers.add(new CreatureSimulator(blocker));
|
||||||
|
TreeNode<CombatSimulator> child = new TreeNode<CombatSimulator>(combat);
|
||||||
|
node.addChild(child);
|
||||||
|
addBlockSimulations(subList, child, game);
|
||||||
|
combat.simulate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Permanent> remove(List<Permanent> source, Permanent element) {
|
||||||
|
List<Permanent> newList = new ArrayList<Permanent>();
|
||||||
|
for (Permanent permanent: source) {
|
||||||
|
if (!permanent.equals(element)) {
|
||||||
|
newList.add(permanent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CombatSimulator getBestSimulation(TreeNode<CombatSimulator> simulations) {
|
||||||
|
CombatSimulator best = simulations.getData();
|
||||||
|
int bestResult = best.evaluate();
|
||||||
|
for (TreeNode<CombatSimulator> node: simulations.getChildren()) {
|
||||||
|
CombatSimulator bestSub = getBestSimulation(node);
|
||||||
|
if (bestSub.evaluate() > bestResult) {
|
||||||
|
best = node.getData();
|
||||||
|
bestResult = best.evaluate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CombatSimulator getWorstSimulation(TreeNode<CombatSimulator> simulations) {
|
||||||
|
CombatSimulator worst = simulations.getData();
|
||||||
|
int worstResult = worst.evaluate();
|
||||||
|
for (TreeNode<CombatSimulator> node: simulations.getChildren()) {
|
||||||
|
CombatSimulator worstSub = getWorstSimulation(node);
|
||||||
|
if (worstSub.evaluate() < worstResult) {
|
||||||
|
worst = node.getData();
|
||||||
|
worstResult = worst.evaluate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return worst;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Permanent> threats(UUID playerId, TargetPermanent target, Game game) {
|
||||||
|
List<Permanent> threats = game.getBattlefield().getActivePermanents(target.getFilter());
|
||||||
|
Iterator<Permanent> it = threats.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
Permanent permanent = it.next();
|
||||||
|
if (!permanent.getControllerId().equals(playerId)) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(threats, new PermanentComparator(game));
|
||||||
|
return threats;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logState(Game game) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("computer player hand: ");
|
||||||
|
for (Card card: hand.values()) {
|
||||||
|
sb.append(card.getName()).append(",");
|
||||||
|
}
|
||||||
|
logger.fine(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playRemoval(List<UUID> attackers, Game game) {
|
||||||
|
for (UUID attackerId: attackers) {
|
||||||
|
for (Card card: this.playableInstant) {
|
||||||
|
if (card.getSpellAbility().canActivate(playerId, game)) {
|
||||||
|
for (Effect effect: card.getSpellAbility().getEffects()) {
|
||||||
|
if (effect.getOutcome().equals(Outcome.DestroyPermanent) || effect.getOutcome().equals(Outcome.Damage)) {
|
||||||
|
if (card.getSpellAbility().getTargets().get(0).canTarget(attackerId, game)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int evaluateState(GameState state, Game game) {
|
||||||
|
int value = life;
|
||||||
|
Player opponent = game.getPlayer(game.getOpponents(playerId).get(0));
|
||||||
|
if (opponent.getLife() <= 0)
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
value -= opponent.getLife();
|
||||||
|
for (Permanent permanent: state.getBattlefield().getAllPermanents()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
52
Mage.Player.AI/src/mage/player/ai/PermanentComparator.java
Normal file
52
Mage.Player.AI/src/mage/player/ai/PermanentComparator.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class PermanentComparator implements Comparator<Permanent> {
|
||||||
|
|
||||||
|
private Game game;
|
||||||
|
private PermanentEvaluator evaluator = new PermanentEvaluator();
|
||||||
|
|
||||||
|
public PermanentComparator(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(Permanent o1, Permanent o2) {
|
||||||
|
return evaluator.evaluate(o1, game) - evaluator.evaluate(o2, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
71
Mage.Player.AI/src/mage/player/ai/PermanentEvaluator.java
Normal file
71
Mage.Player.AI/src/mage/player/ai/PermanentEvaluator.java
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.Constants.CardType;
|
||||||
|
import mage.Constants.Zone;
|
||||||
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
|
import mage.abilities.keyword.FirstStrikeAbility;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class PermanentEvaluator {
|
||||||
|
|
||||||
|
private Map<UUID, Integer> values = new HashMap<UUID, Integer>();
|
||||||
|
|
||||||
|
public int evaluate(Permanent permanent, Game game) {
|
||||||
|
if (!values.containsKey(permanent.getId())) {
|
||||||
|
int value = 0;
|
||||||
|
if (permanent.getCardType().contains(CardType.CREATURE)) {
|
||||||
|
if (permanent.canAttack(game))
|
||||||
|
value += 2;
|
||||||
|
value += permanent.getPower().getValue();
|
||||||
|
value += permanent.getToughness().getValue();
|
||||||
|
value += permanent.getAbilities().getEvasionAbilities().size();
|
||||||
|
value += permanent.getAbilities().getProtectionAbilities().size();
|
||||||
|
value += permanent.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0;
|
||||||
|
value += permanent.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0;
|
||||||
|
value += permanent.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0;
|
||||||
|
}
|
||||||
|
value += permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD).size();
|
||||||
|
value += permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD).size();
|
||||||
|
values.put(permanent.getId(), value);
|
||||||
|
}
|
||||||
|
return values.get(permanent.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai.simulators;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class CombatGroupSimulator implements Serializable {
|
||||||
|
public List<CreatureSimulator> attackers = new ArrayList<CreatureSimulator>();
|
||||||
|
public List<CreatureSimulator> blockers = new ArrayList<CreatureSimulator>();
|
||||||
|
public UUID defenderId;
|
||||||
|
public boolean defenderIsPlaneswalker;
|
||||||
|
public int unblockedDamage;
|
||||||
|
private CreatureSimulator attacker;
|
||||||
|
|
||||||
|
public CombatGroupSimulator(UUID defenderId, List<UUID> attackers, List<UUID> blockers, Game game) {
|
||||||
|
this.defenderId = defenderId;
|
||||||
|
for (UUID attackerId: attackers) {
|
||||||
|
Permanent permanent = game.getPermanent(attackerId);
|
||||||
|
this.attackers.add(new CreatureSimulator(permanent));
|
||||||
|
}
|
||||||
|
for (UUID blockerId: blockers) {
|
||||||
|
Permanent permanent = game.getPermanent(blockerId);
|
||||||
|
this.blockers.add(new CreatureSimulator(permanent));
|
||||||
|
}
|
||||||
|
//NOTE: assumes no banding
|
||||||
|
attacker = this.attackers.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasFirstOrDoubleStrike() {
|
||||||
|
for (CreatureSimulator creature: attackers) {
|
||||||
|
if (creature.hasDoubleStrike || creature.hasFirstStrike)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (CreatureSimulator creature: blockers) {
|
||||||
|
if (creature.hasDoubleStrike || creature.hasFirstStrike)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canBlock(Permanent blocker, Game game) {
|
||||||
|
return blocker.canBlock(attacker.id, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void simulateCombat() {
|
||||||
|
unblockedDamage = 0;
|
||||||
|
|
||||||
|
if (hasFirstOrDoubleStrike())
|
||||||
|
assignDamage(true);
|
||||||
|
assignDamage(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assignDamage(boolean first) {
|
||||||
|
if (blockers.size() == 0) {
|
||||||
|
if (canDamage(attacker, first))
|
||||||
|
unblockedDamage += attacker.power;
|
||||||
|
}
|
||||||
|
else if (blockers.size() == 1) {
|
||||||
|
CreatureSimulator blocker = blockers.get(0);
|
||||||
|
if (canDamage(attacker, first)) {
|
||||||
|
if (attacker.hasTrample) {
|
||||||
|
int lethalDamage = blocker.getLethalDamage();
|
||||||
|
if (attacker.power > lethalDamage) {
|
||||||
|
blocker.damage += lethalDamage;
|
||||||
|
unblockedDamage += attacker.power - lethalDamage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blocker.damage += attacker.power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canDamage(blocker, first)) {
|
||||||
|
attacker.damage += blocker.power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int damage = attacker.power;
|
||||||
|
for (CreatureSimulator blocker: blockers) {
|
||||||
|
if (damage > 0 && canDamage(attacker, first)) {
|
||||||
|
int lethalDamage = blocker.getLethalDamage();
|
||||||
|
if (damage > lethalDamage) {
|
||||||
|
blocker.damage += lethalDamage;
|
||||||
|
damage -= lethalDamage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blocker.damage += damage;
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canDamage(blocker, first)) {
|
||||||
|
attacker.damage += blocker.power;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (damage > 0) {
|
||||||
|
if (attacker.hasTrample) {
|
||||||
|
unblockedDamage += damage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blockers.get(0).damage += damage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canDamage(CreatureSimulator creature, boolean first) {
|
||||||
|
if (first && (creature.hasFirstStrike || creature.hasDoubleStrike))
|
||||||
|
return true;
|
||||||
|
if (!first && (!creature.hasFirstStrike || creature.hasDoubleStrike))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns 3 attacker survives blockers destroyed
|
||||||
|
* returns 2 both destroyed
|
||||||
|
* returns 1 both survive
|
||||||
|
* returns 0 attacker destroyed blockers survive
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int evaluateCombat() {
|
||||||
|
int survivingBlockers = 0;
|
||||||
|
for (CreatureSimulator blocker: blockers) {
|
||||||
|
if (blocker.damage < blocker.toughness)
|
||||||
|
survivingBlockers++;
|
||||||
|
}
|
||||||
|
if (attacker.isDead()) {
|
||||||
|
if (survivingBlockers > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (survivingBlockers > 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai.simulators;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.combat.CombatGroup;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class CombatSimulator implements Serializable {
|
||||||
|
|
||||||
|
public List<CombatGroupSimulator> groups = new ArrayList<CombatGroupSimulator>();
|
||||||
|
public List<UUID> defenders = new ArrayList<UUID>();
|
||||||
|
public Map<UUID, Integer> playersLife = new HashMap<UUID, Integer>();
|
||||||
|
public Map<UUID, Integer> planeswalkerLoyalty = new HashMap<UUID, Integer>();
|
||||||
|
public UUID attackerId;
|
||||||
|
public int rating = 0;
|
||||||
|
|
||||||
|
public static CombatSimulator load(Game game) {
|
||||||
|
CombatSimulator simCombat = new CombatSimulator();
|
||||||
|
for (CombatGroup group: game.getCombat().getGroups()) {
|
||||||
|
simCombat.groups.add(new CombatGroupSimulator(group.getDefenderId(), group.getAttackers(), group.getBlockers(), game));
|
||||||
|
}
|
||||||
|
for (UUID defenderId: game.getCombat().getDefenders()) {
|
||||||
|
simCombat.defenders.add(defenderId);
|
||||||
|
Player player = game.getPlayer(defenderId);
|
||||||
|
if (player != null) {
|
||||||
|
simCombat.playersLife.put(defenderId, player.getLife());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Permanent permanent = game.getPermanent(defenderId);
|
||||||
|
simCombat.planeswalkerLoyalty.put(defenderId, permanent.getLoyalty().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return simCombat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombatSimulator() {}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
groups.clear();
|
||||||
|
defenders.clear();
|
||||||
|
attackerId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void simulate() {
|
||||||
|
for (CombatGroupSimulator group: groups) {
|
||||||
|
group.simulateCombat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int evaluate() {
|
||||||
|
Map<UUID, Integer> damage = new HashMap<UUID, Integer>();
|
||||||
|
int result = 0;
|
||||||
|
for (CombatGroupSimulator group: groups) {
|
||||||
|
if (!damage.containsKey(group.defenderId)) {
|
||||||
|
damage.put(group.defenderId, group.unblockedDamage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
damage.put(group.defenderId, damage.get(group.defenderId) + group.unblockedDamage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check for lethal damage to player
|
||||||
|
for (Entry<UUID, Integer> entry: playersLife.entrySet()) {
|
||||||
|
if (damage.containsKey(entry.getKey()) && entry.getValue() <= damage.get(entry.getKey())) {
|
||||||
|
//TODO: check for protection
|
||||||
|
//NOTE: not applicable for mulitplayer games
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CombatGroupSimulator group: groups) {
|
||||||
|
result += group.evaluateCombat();
|
||||||
|
}
|
||||||
|
|
||||||
|
rating = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The views and conclusions contained in the software and documentation are those of the
|
||||||
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mage.player.ai.simulators;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.UUID;
|
||||||
|
import mage.abilities.keyword.DoubleStrikeAbility;
|
||||||
|
import mage.abilities.keyword.FirstStrikeAbility;
|
||||||
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
*/
|
||||||
|
public class CreatureSimulator implements Serializable {
|
||||||
|
public UUID id;
|
||||||
|
public int damage;
|
||||||
|
public int power;
|
||||||
|
public int toughness;
|
||||||
|
public boolean hasFirstStrike;
|
||||||
|
public boolean hasDoubleStrike;
|
||||||
|
public boolean hasTrample;
|
||||||
|
|
||||||
|
public CreatureSimulator(Permanent permanent) {
|
||||||
|
this.id = permanent.getId();
|
||||||
|
this.damage = permanent.getDamage();
|
||||||
|
this.power = permanent.getPower().getValue();
|
||||||
|
this.toughness = permanent.getToughness().getValue();
|
||||||
|
this.hasDoubleStrike = permanent.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId());
|
||||||
|
this.hasFirstStrike = permanent.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId());
|
||||||
|
this.hasTrample = permanent.getAbilities().containsKey(TrampleAbility.getInstance().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead() {
|
||||||
|
return damage >= toughness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLethalDamage() {
|
||||||
|
return toughness - damage;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue