This commit is contained in:
BetaSteward 2010-04-12 01:34:42 +00:00
parent 8a11870c40
commit 940a0f2cad
27 changed files with 2222 additions and 0 deletions

74
Mage.Player.AI/build.xml Normal file
View 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/dist/Mage.Player.AI.jar vendored Normal file

Binary file not shown.

33
Mage.Player.AI/dist/README.TXT vendored Normal file
View 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

Binary file not shown.

View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

View 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 &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;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>

View 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

View 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

View 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>

View 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

View 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>

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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());
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}