Главная | Описание языка | FXD | API | Примеры | Инструменты Разработки | Новости | Ресурсы | Форум
Описание[]
В конкурсе ГалактикаFX вам нужно запрграммировать автоматический космический корабль для сбора ресурсов в отдаленных частях галактики. Корабль управляется с помощью команд. Соревнование проводится между несколькими кораблями. Побеждает тот корабль, который соберет ресурсов на наибольшую стоимость.
Все подробности о конкурсе можно узнать на сайте:
Установка Игры[]
Описание проекта 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 - следующая управляющая команда
Переменные, доступные программе[]
Переменные[]
- 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(), не учитываются.
Пример программы[]
В коде ниже приведен пример простейшего алгоритма по сбору ресурсов:
- Если предыдущее действие исполнилось до конца
- Если трюм полный, лететь к первому терминалу и разгрузить собранные ресурсы
- Иначе лететь к первому ресурсу и разработать его до конца
- Иначе не прерывать текущую исполняемую программу
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
Одноходовые стратегии[]
Одноходовые стратегии выбирают из всех возможных ресурсов только один для последующего сбора.
Сбор ближайшего ресурса к кораблику:
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;
}
Сбор самого дорогостоящего ресурса:
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 ];
}
Сбор самых дорогостоящих ресурсов:
public function calculateOptimalTrajectory(resources:ResourceItem[]):ResourceItem[]{
return resources[resource| 20 < resource.value];
}
Сканирование пространства[]
Карта содержит расположение ресурсов, корабликов и терминалов на момент последнего сканирования. Чтобы обновить содержимое карты, надо отсканировать пространство. На это тратится определенное время: 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)