JavaFX
Advertisement

Главная | Описание языка | FXD | API | Примеры | Инструменты Разработки | Новости | Ресурсы | Форум

GalaxyFX

Описание[]

В конкурсе ГалактикаFX вам нужно запрграммировать автоматический космический корабль для сбора ресурсов в отдаленных частях галактики. Корабль управляется с помощью команд. Соревнование проводится между несколькими кораблями. Побеждает тот корабль, который соберет ресурсов на наибольшую стоимость.

Все подробности о конкурсе можно узнать на сайте:

http://www.electricjungle.ru


Установка Игры[]

Установите NetBeans с JavaFX плагином
Скачайте проект GalaxyFX
Откройте проект GalaxyFX в NetBeans


Описание проекта GalaxyFX[]

Откройте проект GalaxyFX в NetBeans с установленным JavaFX плагином.

папка galaxyfx
Main.fx - файл для запуска игры
MyFirstProgram.fx - каркас программы, управления корабликом, в котором надо реализовать алгоритм сбора ресурсов
MyMap.fx - тренировачная карта игрового мира, которую можно редактировать
папка galaxyfx.programs - содержит примеры программ, победивших или учавствовавших в промежуточных этапах конкурса GalaxyFX

Программа управлением автоматическим космическим кораблем[]

Каркас программы управления автоматическим космическим кораблем выглядит следующим образом:

import galaxyfx.program.*;
import galaxyfx.program.action.*;

Program{
    name: "My GalaxyFX Program"

    public override function setup():Void{}

    public override function nextStep():Action{
        if (action == null) {
            // return next action
        } 
        return null;
    }
        
}


setup() - инициализация программы
nextStep():Action - следующая управляющая команда


Переменные, доступные программе[]

Переменные[]

GalaxyFX API

cargo - количество собранных ресурсов
cargoCapacity - максимальная вместимость корабля
autoHarvest - автоматическая отправка ресурсов на терминал при полной загрузке корабля
score - количество сданных ресурсов на терминале


position - координаты корабля
direction - направление корабля


time - текущее время

Карта и радар[]

Карта и радар - это переменные, доступные вашей программе.

map - карта
map.timestamp - время последнего обновления карты
map.resources - последовательность ресурсов
map.spacecrafts - последовательность кораблей
map.terminals - последовательность пунктов сбора ресурсов
map.spaceScanTime - время сканирования карты
map.gameTime - время окончания сбора ресурсов. все терминалы закрываются и улетают на Землю


radar - радар
radar.range - радиус действия радара
radar.resources - последовательность ресурсов
radar.spacecrafts - последовательность кораблей
radar.terminals - последовательность пунктов сбора ресурсов

Опции[]

options дополнительные опции позволяющие усовершенствовать корабль
cargo - увеличение вместимости корабля
speed - увеличение скорости корабля
radar - увеличение дальности радара
teamwork - увеличение скорости выполнения команд

Всего дается 4 усовершенствования, которые можно распределить мужду всеми опциями. Максимальное количество усовершенствований на одну опцию - 3.

Примеры:

    TuningOptions {
        cargo: 2,
        speed: 2,
        teamwork: 0,
        radar: 0
    }
    TuningOptions {
        cargo: 0,
        speed: 0,
        teamwork: 3,
        radar: 1
    }


Опции можно устанавливать или в момент инициализации программы, или в методе setup(). Опции, выставленные в методе nextStep(), не учитываются.

Пример программы[]

Galaxyfx simpleprogram

В коде ниже приведен пример простейшего алгоритма по сбору ресурсов:

Если предыдущее действие исполнилось до конца
Если трюм полный, лететь к первому терминалу и разгрузить собранные ресурсы
Иначе лететь к первому ресурсу и разработать его до конца
Иначе не прерывать текущую исполняемую программу


import galaxyfx.program.*;
import galaxyfx.program.action.*;

Program{
    
    autoHarvest: false
    name: "My First GalaxyFX Program"

    public override function setup():Void{}

    public override function nextStep():Action{
        if (action == null) {
            if (cargoCapacity == cargo) {
                return CompoundAction {
                    actions: [
                            MoveAction { path: [map.terminals[0]] },
                            UnloadAction { limit: cargo }
                        ]
                }
            }else{
                var resource = map.resources[0];
                return CompoundAction {
                    actions: [
                            MoveAction { path: [resource] },
                            HarvestAction { limit: resource.value }
                        ]
                }
            }
        }
        return null;
    }
}

Команды управлением автоматическим космическим кораблем[]

Сканирование карты[]

SpaceScanAction{}

Полет по траектории[]

MoveAction { path: [ point1, point2, .. pointN] }

Сбор ресурса[]

HarvestAction { limit: resource.value }

Разгрузка ресурса[]

UnloadAction {}

Составное действие[]

CompoundAction{ actions: [action1, action2, ..., actionN] }



Сортировка ресурсов[]

Язык JavaFX Script позволяет отсортировать последовательность с помощью методов:

Sequences.sort(sequence)
Sequences.sort(sequence, comparator)

Например сортировка ресурсов по их стоимости будет выглядеть следующим образом:

  function sign(x:Number):Integer{
    if ( x < 0 ) { -1 } else if ( 0 < x ) { 1 } else  { 0 }
  }

  var sorted = Sequences.sort(resources, Comparator{
            public override function compare(obj1 : Object, obj2 : Object): Integer{
                var r1 = (obj1 as ResourceItem);
                var r2 = (obj2 as ResourceItem);
                var delta = r2.value - r1.value;
                return sign(delta);
            }
        }
    ) as ResourceItem[];


Введем вспомогательную функцию sort для сортировки ресурсов, которая зависит от последовательности ресурсов и от функции сравнения 2х ресурсов:

function sort(resources:ResourceItem[], compare:function(ResourceItem,ResourceItem):Integer){
    return Sequences.sort(resources, Comparator{
            public override function compare(obj1 : Object, obj2 : Object): Integer{
                return compare(obj1 as ResourceItem, obj2 as ResourceItem);
            }
        }
    ) as ResourceItem[];
}


Стратегии[]

Если брать за основу простейший алгоритм по сбору ресурсов, то в программе остается только определить оптимальный маршрут по сбору ресурсов и разгрузку их на терминале.

Введем метод calculateOptimalTrajectory который будет возвращать оптимальный маршрут сбора ресурсов.

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{
        return resources;
    }


С помощью метода calculateOptimalTrajectory можно получить оптимальный маршрут по сбору ресурсов и составить командо по их облету и сбору:

                var resources = calculateOptimalTrajectory(map.resources);
                CompoundAction {
                    actions: for (r in resources)[
                            MoveAction { path: [r] },
                            HarvestAction { limit: r.value }
                        ]
                }


Тогда вся программа будет выглядеть следующим образом:

import galaxyfx.program.*;
import galaxyfx.program.action.*;

import galaxyfx.program.*;
import galaxyfx.program.action.*;

import galaxyfx.spacecraft.system.ResourceItem;

Program{

    autoHarvest: false
    name: "My First GalaxyFX Program"

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{
        return resources;
    }

    public override function setup():Void{}

    public override function nextStep():Action{
        if (action == null) {
            if (cargoCapacity == cargo) {
                return CompoundAction {
                    actions: [
                            MoveAction { path: [map.terminals[0]] },
                            UnloadAction { limit: cargo }
                        ]
                }
            }else{
                var resources = calculateOptimalTrajectory(map.resources);
                return CompoundAction {
                    actions: for (r in resources)[
                            MoveAction { path: [r] },
                            HarvestAction { limit: r.value }
                        ]
                }
            }
        }
        return null;
    }
}

Мы же сосредоточимся на разработке метода calculateOptimalTrajectory

Одноходовые стратегии[]

Одноходовые стратегии выбирают из всех возможных ресурсов только один для последующего сбора.


Сбор ближайшего ресурса к кораблику:

Galaxyfx onestep nearest distance

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{

        var distance = Number.MAX_VALUE;
        var resource:ResourceItem;

        for(r in resources){
            var d = Point.distance(r, position) ;
            if( d < distance){
                distance = d;
                resource = r;
            }
        }

        return resource;
    }

Сбор ближайшего по времени ресурса:


    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{

        var time = Number.MAX_VALUE;
        var resource:ResourceItem;

        for(r in resources){
            var t = distanceTime(r);
            if( t < time){
                time = t;
                resource = r;
            }
        }

        return resource;
    }


Сбор самого дорогостоящего ресурса:

Galaxyfx onestep nearest value

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{

        var value = 0.0;
        var resource:ResourceItem;

        for(r in resources){
            if( value < r.value){
                value = r.value;
                resource = r;
            }
        }

        return resource;
    }


Многоходовые стратегии[]

Многоходовые стратегии выбирают сразу несколько ресурсов для сбора в ходе исполнения одной команды.

Язык JavaFX Script позволяет делать выборку элементов и последовательности по некоторому условию:

  var subSeq =  seq[n| condition(n) ];

Сбор ближайших ресурсов:

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{
        return resources[resource| Point.distance(resource,position) < 300 ];
    }


Сбор самых дорогостоящих ресурсов:

Galaxyfx multistep value

    public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{
        return resources[resource| 20 < resource.value];
    }

Сканирование пространства[]

Galaxyfx strategy spacescan

Карта содержит расположение ресурсов, корабликов и терминалов на момент последнего сканирования. Чтобы обновить содержимое карты, надо отсканировать пространство. На это тратится определенное время: map.spaceScanTime

Одна из простейших стратигий заключается в сканировании пространства через определенные моменты времени:

 if (200 < time - map.timestamp){
    return SpaceScanAction{};
 }


Стандартные алгоритмы[]

Отчаянный старатель[]

import galaxyfx.program.*;
import galaxyfx.program.action.*;

Program{

    public override function setup():Void{ }

    public override function nextStep():Action{
       if (action == null) MoveAction{path: map.resources} else null;
    }
}


Осторожный старатель[]

import galaxyfx.program.*;
import galaxyfx.program.action.*;

Program{

    public override function setup():Void{ }

    public override function nextStep():Action{
        if (action == null) {
            if (200 < time - map.timestamp){
                return SpaceScanAction{};
            } else {
                return MoveAction{path: map.resources[0]};
            }
        }
        return null;
    }
}


Осторожный старатель[]

import galaxyfx.program.*;
import galaxyfx.program.action.*;

Program{

    public override function setup():Void{ }

    public override function nextStep():Action{
        if (action == null) {
            if (sizeof radar.resources > 0) {
                return MoveAction{path: radar.resources}
            } else if (200 < time - map.timestamp){
                return SpaceScanAction{};
            } else {
                return MoveAction{path: map.resources[0]};
            }
        }
        return null;
    }
}


FAQ[]

Форум[]

Официальный форум конкурса GalaxyFX: Forum

Расстояние между ресурсами, кораблями, терминалами[]

 Point.distance( resource1, resource2 )

Время полета[]

 distanceTime(resources)
Advertisement