Toto je dokumentácia k našej Špongia hre KSP. V tejto hre dokáže používateľ vytvárať vlastných botov v LuaScript ktorí následne fungujú ako agent v hre.
Cieľ hry
Krátkodobý cieľ
V hre hrajú proti sebe dvaja hráči. Každý z nich má na začiatku nejaké svoje planéty. Každá z planét v pravidelnom intervale generuje vesmírne lode. Hráči dokážu posielať vesmírne lode na iné planéty:
- Ak pošlem lode na svoju planétu, počet lodí na danej planéte bude súčtom poslaných a lodí, ktoré tam už boli.
- Ak pošlem lode na cudziu planétu, tak každá poslaná loď zníži počet tamojších lodí o 1. Akonáhle by počet mal ísť do záporu, vysielací hráč planétu získa.
Cieľom je takýmto spôsobom získať všetky planéty.
Dlhodobý cieľ
Hráči si vedia generovať botov. Boti sa píšu v jazyku Lua, nižšie je popísaná dokumentácia. Boti sa dajú pridávať na stránke
Pri vstupe do hry si hráč bude môcť z db vybrať, ktorých dvoch botov proti sebe pustí (alebo jedného z nich nahradí sebou). Každý zápas bude mať víťaza a porazeného.
Každý bot má svoje ELO. Po každom zápase sa mu ELO zmení vzorčekom rovnakým ako pri šachu. Na stránke ranking je vidieť aktuálne poradie všetkých botov. Cieľom každého bota je byť čo najlepší a mať čo najvyššie ELO.
Controls
Ked sa hráte ako player, tak hru kontrolujete nasledovne:
- Na poslanie lodí medzi dvoma planétami najskôr označíte svoju a potom planétu
- Ak pošlem lode na cudziu planétu, tak každá poslaná loď zníži počet tamojších lodí o 1. Akonáhle by počet mal ísť do záporu, vysielací hráč planétu získa.
Herný cyklus
Hra funguje takto (pri default settings, konštanty sa môžu meniť):
20 krát za sekundu sa odohrá kolo - aj keď hra možno vyzerá realtime, všetko beží na takéto kolá. V kole sa stane po rade toto:
player1.Execute()
- ak je tento hráč fyzický hráč, teda inštanciaPhysicalPlayer
tak toto neurobí nič. Ak je inštanciaBotPlayer
, tak to TOMTO BODE ZBEHNE VÁŠ LUA KÓD.player2.Execute()
- to isté pre druhého hráča.- Pridá každej planéte units podľa levelu. V pozadí má každá planéta hodnotu
getsUnitInTurns
, ktorá sa znižuje každým kolom, až kým nedosiahne 0, kedy pridá planéte unit a resetuje sa. - Executnú sa všetky
Action
hráča 1. - Executnú sa všetky
Action
hráča 2. - Skontroluje sa, či niekto nevyhral.
Lua Globals
Ako botovi v Lua vám sú exposed základne funkcie a to:
Typy
Planet
using UnityEngine;
using UnityEngine;
namespace DefaultNamespace
{
public class Planet
{
internal int level = 0;
internal int units = 0;
internal int getsUnitInTurns;
internal Player owner;
internal Vector2 position;
internal int maxUnits;
public int Level => level;
public int Units => units;
public int GetsUnitInTurns => getsUnitInTurns;
public Player Owner => owner;
public Vector2 Position => position;
}
}
Constants
Tieto konštanty viete accessovať:
namespace DefaultNamespace
{
public class Constants
{
public const int TURNS_PER_SECOND = 20;
public const int MAX_LEVEL = 5;
public const float TRAVEL_SPEED = 0.05f;
public static readonly int[] PRODUCTION_PER_TURN_BY_LEVEL = new int[MAX_LEVEL] { 20, 15, 10, 8, 5 };
public static readonly int[] MAX_CAPACITY_BY_LEVEL = new int[MAX_LEVEL] { 10, 20, 25, 35, 50 };
public static readonly int[] UPGRADE_COST_PER_LEVEL = new int[MAX_LEVEL - 1] { 5, 10, 20, 30 };
}
}
Player
Abstract class z ktorej dedia BotPlayer
aj PhysicalPlayer
. Tieto dve nemajú žiadnu ďalšiu funkcionalitu accessible cez bota.
using System.Collections.Generic;
namespace DefaultNamespace
{
public abstract class Player
{
internal PlayerNumber playerNum;
internal List<GameAction> actions;
internal string humanReadableName;
internal Player(PlayerNumber number)
{
playerNum = number;
humanReadableName = "Physical";
actions = new List<GameAction>();
}
internal abstract void Execute();
public PlayerNumber PlayerNum => playerNum;
public string HumanReadableName => humanReadableName;
}
public enum PlayerNumber{
Player1,Player2,None
}
}
Vector3
Každá planéta je definovaná ako Vector v Unity.
Funkcie
get_planets
get_planets
syntax vyzerá takto:
allPlanets = get_planets()
Returns: Planet[]
upgrade
upgrade
syntax vyzerá takto:
upgrade(myPlanet)
Pridá UpgradeAction(myPlanet)
na koniec Player.actions
send_units
send_units
syntax vyzerá takto:
send_units(origin, target, amount)
Pridá SendUnitsAction(origin, target, amount)
na koniec Player.actions
log
log
syntax vyzerá takto:
log("hello world")
Priamo sa logguje na obrazovku.
Príklady botov
Tu sú príklady jednoduchých botov:
Dumbbot
Tento bot posiela unity až kým nemôže, a skúša sa upgradovať.
function getMyPlanets(planets)
myPlanets = {}
index = 1
for i = 1, #planets do
if planets[i].Owner == bot then
myPlanets[index] = planets[i]
index = index +1
end
end
return myPlanets
end
function getOpponentPlanets(planets)
opponentPlanets = {}
index = 1
for i = 1, #planets do
if planets[i].Owner ~= bot then
opponentPlanets[index] = planets[i]
index = index + 1
end
end
return opponentPlanets
end
function turn()
planets = get_planets()
myPlanets = getMyPlanets(planets)
opponentPlanets = getOpponentPlanets(planets)
if #opponentPlanets == 0 then
return
end
for i = 1, #myPlanets do
planet = myPlanets[i]
if planet.Level < 4 then
if planet.Units >= Constants.UPGRADE_COST_PER_LEVEL[planet.Level+1] + 5 then
upgrade(planet)
end
end
send_units(myPlanets[i],opponentPlanets[1],1)
end
end