added First bot with logging
This commit is contained in:
221
DDApp/DDApplication/BotSessionLogger.cs
Normal file
221
DDApp/DDApplication/BotSessionLogger.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace DDApplication;
|
||||
|
||||
internal sealed class BotSessionLogger : IDisposable
|
||||
{
|
||||
private readonly object _gate = new();
|
||||
private readonly DateTimeOffset _startedAt = DateTimeOffset.UtcNow;
|
||||
private readonly Dictionary<string, int> _actionAttempts = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, int> _actionSuccess = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private StreamWriter? _eventsWriter;
|
||||
private bool _disposed;
|
||||
|
||||
public string SessionId { get; } = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
|
||||
public string DirectoryPath { get; }
|
||||
public string EventsPath { get; }
|
||||
public string SummaryPath { get; }
|
||||
public string LatestSymlinkPath { get; }
|
||||
|
||||
public BotSessionLogger()
|
||||
{
|
||||
var baseDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
DirectoryPath = Path.Combine(baseDir, "DDApplication", "logs");
|
||||
Directory.CreateDirectory(DirectoryPath);
|
||||
|
||||
var stamp = DateTimeOffset.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);
|
||||
EventsPath = Path.Combine(DirectoryPath, $"bot_{stamp}_{SessionId}.events.csv");
|
||||
SummaryPath = Path.Combine(DirectoryPath, $"bot_{stamp}_{SessionId}.summary.txt");
|
||||
LatestSymlinkPath = Path.Combine(DirectoryPath, "latest.log");
|
||||
|
||||
_eventsWriter = new StreamWriter(EventsPath, append: false, Encoding.UTF8) { AutoFlush = true };
|
||||
_eventsWriter.WriteLine("timestamp_utc,event,label,executed,hp,max_hp,kills,deaths,pos_x,pos_y,pressure,details");
|
||||
UpdateLatestSymlink();
|
||||
}
|
||||
|
||||
public void LogDecision(
|
||||
string label,
|
||||
bool executed,
|
||||
double hp,
|
||||
double maxHp,
|
||||
int kills,
|
||||
int deaths,
|
||||
int x,
|
||||
int y,
|
||||
bool pressure,
|
||||
string details)
|
||||
{
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed || _eventsWriter is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Increment(_actionAttempts, label);
|
||||
if (executed)
|
||||
{
|
||||
Increment(_actionSuccess, label);
|
||||
}
|
||||
|
||||
_eventsWriter.WriteLine(string.Join(",",
|
||||
Csv(DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)),
|
||||
Csv("decision"),
|
||||
Csv(label),
|
||||
Csv(executed ? "1" : "0"),
|
||||
Csv(hp.ToString("0.00", CultureInfo.InvariantCulture)),
|
||||
Csv(maxHp.ToString("0.00", CultureInfo.InvariantCulture)),
|
||||
Csv(kills.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(deaths.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(x.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(y.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(pressure ? "1" : "0"),
|
||||
Csv(details)));
|
||||
}
|
||||
}
|
||||
|
||||
public void LogTelemetry(
|
||||
double hp,
|
||||
double maxHp,
|
||||
int kills,
|
||||
int deaths,
|
||||
double progress,
|
||||
double remaining,
|
||||
string level,
|
||||
int x,
|
||||
int y,
|
||||
string details)
|
||||
{
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed || _eventsWriter is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_eventsWriter.WriteLine(string.Join(",",
|
||||
Csv(DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)),
|
||||
Csv("telemetry"),
|
||||
Csv(level),
|
||||
Csv(""),
|
||||
Csv(hp.ToString("0.00", CultureInfo.InvariantCulture)),
|
||||
Csv(maxHp.ToString("0.00", CultureInfo.InvariantCulture)),
|
||||
Csv(kills.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(deaths.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(x.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(y.ToString(CultureInfo.InvariantCulture)),
|
||||
Csv(""),
|
||||
Csv($"progress={progress:0.00};remaining={remaining:0.00};{details}")));
|
||||
}
|
||||
}
|
||||
|
||||
public void LogEvent(string label, string details)
|
||||
{
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed || _eventsWriter is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_eventsWriter.WriteLine(string.Join(",",
|
||||
Csv(DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)),
|
||||
Csv("event"),
|
||||
Csv(label),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(""),
|
||||
Csv(details)));
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteSummaryAndDispose(double finalHp, double finalMaxHp, int finalKills, int finalDeaths)
|
||||
{
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var elapsed = DateTimeOffset.UtcNow - _startedAt;
|
||||
var minutes = Math.Max(elapsed.TotalMinutes, 0.01);
|
||||
var kd = finalDeaths == 0 ? finalKills : (double)finalKills / finalDeaths;
|
||||
|
||||
var lines = new List<string>
|
||||
{
|
||||
$"session={SessionId}",
|
||||
$"started_utc={_startedAt:O}",
|
||||
$"ended_utc={DateTimeOffset.UtcNow:O}",
|
||||
$"duration_minutes={minutes:0.00}",
|
||||
$"kills={finalKills}",
|
||||
$"deaths={finalDeaths}",
|
||||
$"kd={kd:0.000}",
|
||||
$"kills_per_min={(finalKills / minutes):0.000}",
|
||||
$"deaths_per_min={(finalDeaths / minutes):0.000}",
|
||||
$"final_hp={finalHp:0.00}/{finalMaxHp:0.00}",
|
||||
"actions="
|
||||
};
|
||||
|
||||
foreach (var attempt in _actionAttempts.OrderBy(x => x.Key))
|
||||
{
|
||||
_actionSuccess.TryGetValue(attempt.Key, out var success);
|
||||
var rate = attempt.Value == 0 ? 0 : (double)success / attempt.Value;
|
||||
lines.Add($" {attempt.Key}: attempts={attempt.Value}, success={success}, rate={rate:0.000}");
|
||||
}
|
||||
|
||||
File.WriteAllLines(SummaryPath, lines, Encoding.UTF8);
|
||||
|
||||
_eventsWriter?.Dispose();
|
||||
_eventsWriter = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
WriteSummaryAndDispose(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
private static void Increment(Dictionary<string, int> dict, string key)
|
||||
{
|
||||
dict.TryGetValue(key, out var current);
|
||||
dict[key] = current + 1;
|
||||
}
|
||||
|
||||
private static string Csv(string value)
|
||||
{
|
||||
var safe = value.Replace("\"", "\"\"");
|
||||
return $"\"{safe}\"";
|
||||
}
|
||||
|
||||
private void UpdateLatestSymlink()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(LatestSymlinkPath) || Directory.Exists(LatestSymlinkPath))
|
||||
{
|
||||
File.Delete(LatestSymlinkPath);
|
||||
}
|
||||
|
||||
File.CreateSymbolicLink(LatestSymlinkPath, EventsPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best-effort only; logging should continue even if symlink creation fails.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,47 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
mc:Ignorable="d" d:DesignWidth="1320" d:DesignHeight="860"
|
||||
Width="1320" Height="860"
|
||||
x:Class="DDApplication.MainWindow"
|
||||
Title="DDApplication">
|
||||
<Panel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Label>Welcome to Avalonia!</Label>
|
||||
</Panel>
|
||||
Title="Digital Dojo Bot Controller">
|
||||
<Grid RowDefinitions="Auto,Auto,*,Auto" ColumnDefinitions="2*,2*,3*" Margin="12">
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" Spacing="8">
|
||||
<Button x:Name="StartButton" Content="Start Bot" Width="120"/>
|
||||
<Button x:Name="StopButton" Content="Stop Bot" Width="120" IsEnabled="False"/>
|
||||
<TextBlock Text="API Key:" VerticalAlignment="Center"/>
|
||||
<TextBox x:Name="ApiKeyBox" Width="360" Watermark="GUID player token"/>
|
||||
<TextBlock x:Name="StatusText" VerticalAlignment="Center" Text="Idle"/>
|
||||
</StackPanel>
|
||||
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,8,0,8" Padding="8" BorderThickness="1" CornerRadius="6">
|
||||
<SelectableTextBlock x:Name="StatsText" TextWrapping="Wrap" Text="Waiting for game state..." Focusable="True"/>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="2" Grid.Column="0" Margin="0,0,8,0" Padding="8" BorderThickness="1" CornerRadius="6">
|
||||
<Grid RowDefinitions="Auto,*" RowSpacing="6">
|
||||
<TextBlock Text="Bot Knowledge" FontWeight="Bold"/>
|
||||
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<UniformGrid x:Name="KnowledgeGrid" Rows="21" Columns="21"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="2" Grid.Column="1" Margin="0,0,8,0" Padding="8" BorderThickness="1" CornerRadius="6">
|
||||
<Grid RowDefinitions="Auto,Auto,*" RowSpacing="8">
|
||||
<TextBlock Text="Decision + Cooldowns" FontWeight="Bold"/>
|
||||
<TextBlock x:Name="DecisionText" Grid.Row="1" TextWrapping="Wrap" Text="No decision yet."/>
|
||||
<TextBlock x:Name="CooldownText" Grid.Row="2" TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="2" Grid.Column="2" Padding="8" BorderThickness="1" CornerRadius="6">
|
||||
<Grid RowDefinitions="Auto,*" RowSpacing="6">
|
||||
<TextBlock Text="Action Log" FontWeight="Bold"/>
|
||||
<ListBox x:Name="LogList" Grid.Row="1"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,8,0,0" Text="Legend: P=bot, N=scan-nearest, *=high threat, +=medium threat, .=low threat" />
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,18 +6,17 @@ namespace DDApplication;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
public static IConfiguration Configuration { get; private set; } = null!;
|
||||
public static IConfiguration Configuration { get; private set; } = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddUserSecrets<Program>(optional: true)
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
Configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddUserSecrets<Program>(optional: true)
|
||||
.AddEnvironmentVariables()
|
||||
.Build();
|
||||
return BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
}
|
||||
|
||||
42
DDApp/DDApplication/README.md
Normal file
42
DDApp/DDApplication/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Digital Dojo Bot Controller
|
||||
|
||||
This Avalonia app runs an autonomous bot for the Digital Dojo singleplayer API and visualizes both current game state and inferred enemy knowledge.
|
||||
|
||||
## What it does
|
||||
|
||||
- Starts/uses your current game session (`/api/game/{key}/create`, `/status`)
|
||||
- Runs a cooldown-aware combat loop (`move`, `hit`, `shoot`, `specialattack`, `radar`, `scan`, `peek`, `dash`)
|
||||
- Tries to maximize score by prioritizing fast damage actions when enemies are nearby
|
||||
- Shows live stats (kills/deaths, HP, level progress, remaining time)
|
||||
- Shows a local knowledge map:
|
||||
- `P` = estimated player position
|
||||
- `N` = nearest enemy from latest scan
|
||||
- `* + .` = inferred enemy threat intensity
|
||||
- Shows cooldown timers and action reasoning/logs
|
||||
- Writes per-session analytics logs for post-run analysis
|
||||
|
||||
## Setup
|
||||
|
||||
Set your API key (GUID) in one of these ways:
|
||||
|
||||
1. Environment variable: `APIKEY`
|
||||
2. User secrets (`Program` already loads user secrets)
|
||||
3. Paste it directly into the UI text box before clicking **Start Bot**
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
dotnet run --project /home/tikaiz/RiderProjects/digitalDojo/DDApp/DDApplication/DDApplication.csproj
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Position and map are inferred from your own movement + sensor calls (not an authoritative server map).
|
||||
- The strategy is heuristic and tunable; it is designed for high kill throughput while respecting API cooldowns.
|
||||
- Session logs are written to `~/.local/share/DDApplication/logs` on Linux:
|
||||
- `*.events.csv` contains timestamped telemetry, decisions, and events
|
||||
- `*.summary.txt` contains aggregate K/D, kills/min, deaths/min, and action success rates
|
||||
- `latest.log` is a symlink that auto-points to the newest `*.events.csv` session log
|
||||
|
||||
|
||||
|
||||
633
DDApp/DDApplication/spieleinstieg.txt
Normal file
633
DDApp/DDApplication/spieleinstieg.txt
Normal file
@@ -0,0 +1,633 @@
|
||||
Digital Dojo <https://dd.countit.at/> Menü //
|
||||
|
||||
* //Coden lernen<https://dd.countit.at/programmieren-lernen>
|
||||
o //Programmier-Roadmap <https://dd.countit.at/programmieren-lernen>
|
||||
o //Programmierschule <https://dd.countit.at/programmierschule>
|
||||
o //Übungsräume <https://dd.countit.at/dojos>
|
||||
o //Katas <https://dd.countit.at/katas>
|
||||
o //Tutorials <https://dd.countit.at/tutorials>
|
||||
* //Dojo Game<https://dd.countit.at/dojo-game/multiplayer-modus>
|
||||
o //Besiege unseren Bot <https://dd.countit.at/dojo-game>
|
||||
o //Spieleinstieg <https://dd.countit.at/dojo-game/spieleinstieg>
|
||||
o //Levels & Bots <https://dd.countit.at/dojo-game/levels>
|
||||
o //Leaderboard <https://dd.countit.at/dojo-game/leaderboard>
|
||||
o //Multiplayer Modus <https://dd.countit.at/dojo-game/
|
||||
multiplayer-modus>
|
||||
o //Tipps <https://dd.countit.at/dojo-game/tipps>
|
||||
* //Programmier-Challenge <https://dd.countit.at/programmierwettbewerb>
|
||||
* //Bewerben <https://dd.countit.at/bewerben>
|
||||
* //Feedback <https://dd.countit.at/feedback>
|
||||
* // <#>
|
||||
Ausloggen
|
||||
|
||||
/
|
||||
|
||||
/
|
||||
/
|
||||
|
||||
/
|
||||
|
||||
//Teilen //Facebook <https://www.facebook.com/sharer/sharer.php?
|
||||
u=https%3A%2F%2Fdd.countit.at%2Fdojo-game%2Fspieleinstieg> //Instagram
|
||||
<https://www.instagram.com/count_it_group/> //LinkedIn <https://
|
||||
www.linkedin.com/shareArticle?
|
||||
mini=true&url=https%3A%2F%2Fdd.countit.at%2Fdojo-
|
||||
game%2Fspieleinstieg&title=&summary=&source=> //E-Mail
|
||||
<mailto:m.mustermann@countit.at?subject=Lese-
|
||||
Tipp%3A%20Dojo%20Game%20%7C%20Wichtige%20Infos%20zum%20Spieleinstieg&body=Hey%2C%0D%0A%0D%0Aich%20habe%20auf%20https%3A%2F%2Fkarriere.countit.at%20einen%20Beitrag%20gefunden%2C%20der%20dich%20interessieren%20k%C3%B6nnte%3A%0D%0A%22Dojo%20Game%20%7C%20Wichtige%20Infos%20zum%20Spieleinstieg%22%0D%0ASchau%20ihn%20dir%20mal%20an%3A%20https%3A%2F%2Fkarriere.countit.at%2Fdojo-game%2Fspieleinstieg%3Fkaid%3Dsharemail%0D%0A%0D%0ABeste%20Gr%C3%BC%C3%9Fe>
|
||||
|
||||
|
||||
Spieleinstieg
|
||||
|
||||
|
||||
Dojo Game
|
||||
|
||||
|
||||
//Dojo Game | Dein Einstieg ins Spiel
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
In diesem Abschnitt findest du alle notwendigen Infos, um das Dojo Game
|
||||
zu starten und erste Aktionen durchzuführen.
|
||||
|
||||
*Hinweis: *Hol dir deinen persönlichen Zugang <https://dd.countit.at/
|
||||
register> bevor du startest bzw. logge dich ein <https://dd.countit.at/
|
||||
login>. So erscheinst du später auch am Leaderboard!
|
||||
|
||||
|
||||
Inhaltsverzeichnis
|
||||
|
||||
1. Das Spiel <#spiel>
|
||||
2. Vorbereitung <#vorbereitung>
|
||||
3. API-Schlüssel <#api>
|
||||
4. Spiel starten & beenden <#starten>
|
||||
5. Ritter steuern <#ritter>
|
||||
|
||||
|
||||
//Das Spiel
|
||||
|
||||
Im Dojo Game geht es, einfach erklärt, um einen *Server*, auf welchem
|
||||
ein Spiel für dich bereitgestellt wird. In diesem Spiel gibt es im
|
||||
Singleplayer-Modus *einen Gegner, den sogenannten Dojo-Bot,* und deinen
|
||||
Charakter. *Dein Ritter* hat dieselben Eigenschaften wie ein vom
|
||||
Computer gesteuerter Ritter. Über bestimmte Befehle (diese werden über
|
||||
URLs aufgerufen) kannst du deinen Spieler steuern und so programmieren,
|
||||
dass dieser mit deinen Gegnern kämpft, vor ihnen wegläuft oder andere
|
||||
strategische Aktionen ausführt. Ziel ist es, so viele Gegner wie möglich
|
||||
zu eliminieren.
|
||||
*Ein Spiel dauert maximal 15 Minuten* - danach wird deine Sitzung
|
||||
geschlossen. Es gibt innerhalb dieser 15 Minuten unendlich viele Gegner.
|
||||
Wird ein Bot getötet, wird dieser auf einer zufälligen anderen Stelle
|
||||
der Map wiedergeboren. Bei Start eines neuen Spiels beginnst du immer
|
||||
automatisch neu in Level 1.
|
||||
|
||||
|
||||
//Vorbereitung
|
||||
|
||||
Um am Dojo Game teilzunehmen, benötigst du einen an das Internet
|
||||
angeschlossenen Computer, einen *Digital Dojo Zugang* <https://
|
||||
dd.countit.at/register>. Sobald du eingeloggt <https://dd.countit.at/
|
||||
login> bist, findest du im Folgenden deinen *API-Schlüssel*, den du
|
||||
schon bald brauchen wirst.
|
||||
|
||||
Die Logik deines Spielers kannst du in jeder beliebigen
|
||||
Programmiersprache implementieren, da Web-Requests an eine API von fast
|
||||
jeder verfügbaren Programmier- und Skriptsprache unterstützt werden.
|
||||
|
||||
Falls du Starthilfe benötigst und auf bereits erstellte Algorithmen
|
||||
aufbauen möchtest, kannst du dich hier <https://dd.countit.at/dojo-game/
|
||||
tipps> umsehen.
|
||||
|
||||
Die REST-API Befehle können auch mithilfe vom Fiddler <https://
|
||||
www.telerik.com/fiddler> oder dem Postman <https://www.postman.com/
|
||||
> gesendet werden. Diese Programme werden meistens zum Testen oder für
|
||||
Prototypen verwendet und benötigen keinen Programm-Code zum Funktionieren.
|
||||
|
||||
|
||||
//API-Schlüssel
|
||||
|
||||
Mithilfe deines Keys kannst du dich mit unseren Servern verbinden um
|
||||
dein Spiel zu starten. Zudem werden damit deine gesendeten Befehle
|
||||
identifiziert, damit Aktionen, welche du ausführst, auch wirklich nur
|
||||
für dich gelten. Somit wird verhindert, dass du die Spiele anderer User
|
||||
stören oder manipulieren kannst.
|
||||
|
||||
*Halte deinen Schlüssel geheim* - er könnte es anderen Nutzern
|
||||
ermöglichen, Befehle auszuführen welche nicht in deinem Sinne sind!
|
||||
|
||||
|
||||
//Los geht's
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
In diesem Abschnitt erfährst du, wie du ein Spiel startest und beendest,
|
||||
den Status des laufenden Spiels abfragen kannst, und wie sich dein
|
||||
Ritter steuern lässt.
|
||||
|
||||
|
||||
Wie starte ich ein Spiel? [POST]
|
||||
|
||||
|
||||
Um ein Spiel zu starten, benötigst du deinen API-Schlüssel <#api>. Wurde
|
||||
dieser Befehl erfolgreich ausgeführt, wird das Spiel automatisch
|
||||
gestartet und du kannst direkt Aktionen zum Bewegen des Ritters ausführen.
|
||||
|
||||
Falls bereits ein Spiel mit deinem Charakter läuft, musst du dieses
|
||||
zuerst beenden, bevor du ein neues erstellen kannst. Spiele werden
|
||||
mithilfe eines POST-Requests erzeugt.
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/create
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/create
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#spielstart>
|
||||
|
||||
|
||||
<http://countit-azure-test.westeurope.cloudapp.azure.com:1337/dojo-
|
||||
game/postman#spieleinstieg>
|
||||
|
||||
|
||||
Wie beende ich ein Spiel? [POST]
|
||||
|
||||
|
||||
Ein Spiel wird beendet, wenn du mit deinem API-Key folgenden Befehl als
|
||||
POST-Request ausführst:
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/close
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/close
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#spielende>
|
||||
|
||||
|
||||
Status des laufenden Spiels abfragen [GET]
|
||||
|
||||
|
||||
Um abfragen zu können, ob mit deinem API-Schlüssel bereits ein Spiel
|
||||
läuft, kannst du den folgenden Befehl verwenden. Du erhältst als
|
||||
Rückgabewert dasselbe wie beim Erstellen und Schließen eines Spiels
|
||||
sowie eine Fehlermeldung, falls kein Spiel vorhanden ist.
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/status
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/game/{key}/status
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#status>
|
||||
|
||||
Beim Erstellen und Beenden eines Spiels werden jeweils dieselben Daten
|
||||
zurückgeliefert:
|
||||
|
||||
→ Game-ID: Diese macht dein Spiel identifizierbar.
|
||||
→ Running: Damit werden dein Spielstatus und der Name des geladenen
|
||||
Levels sichtbar.
|
||||
|
||||
Der zurückgegebene String ist im JSON Format.
|
||||
|
||||
{"gameid":"d2144a67-733a-4e06-8a6b-9ce877b99753","running":true,"level":"The Default Level"}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
{"gameid":"d2144a67-733a-4e06-8a6b-9ce877b99753","running":true,"level":"The Default Level"}
|
||||
|
||||
➯ Was ist JSON? <https://dd.countit.at/dojo-game/tipps#technologie>
|
||||
|
||||
|
||||
//Steuere deinen Ritter
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Ein Ritter hat die Möglichkeit auf einem zweidimensionalen Spielfeld
|
||||
verschiedenste Aktionen auszuführen. Aktionen sowie ihre Wirkungen und
|
||||
REST Aufrufe sind hier gelistet. Versuche deine Aktionen nicht zu
|
||||
schnell hintereinander auszuführen, da du nach jeder Aktion eine gewisse
|
||||
Zeit abwarten musst, bis du diese wieder einsetzen kannst. Dein Ritter
|
||||
führt nur Befehle aus, welche du ihm gibst. Sendest du deinem Spieler
|
||||
keine Aktionen, welche dieser ausführen soll, steht dieser durchgehend
|
||||
auf derselben Position und ist verletzbar.
|
||||
|
||||
|
||||
Move [POST]
|
||||
|
||||
|
||||
Du kannst deinen Ritter alle 250 Millisekunden um ein Feld in eine der
|
||||
vier Himmelsrichtungen bewegen.
|
||||
Das Feld "Direction" sollte eine Zahl zwischen 0 und 3 enthalten:
|
||||
|
||||
→ 0 für Norden
|
||||
→ 1 für Osten
|
||||
→ 2 für Süden
|
||||
→ 3 für Westen
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/move/{direction}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/move/{direction}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#move>
|
||||
|
||||
|
||||
Dash [POST]
|
||||
|
||||
|
||||
Dash lässt dich 5 Blöcke in eine von dir bestimmte Richtung bewegen.
|
||||
Es hat außerdem einen besonderen Cooldown: Du kannst Dash schon 3
|
||||
Sekunden nach der Aktivierung verwenden, aber dein Spieler wird zu
|
||||
erschöpft sein und sich nur 3 Blöcke bewegen. Doch aufgepasst, wenn du
|
||||
gegen eine Wand dasht nimmst du Schaden in Höhe der verbleibenden Dash-
|
||||
Distanz. Nachdem du diese Aktion verwendet hast, musst du 5000
|
||||
Millisekunden warten.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/dash/{direction}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/dash/{direction}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#dash>
|
||||
|
||||
|
||||
Hit [POST]
|
||||
|
||||
|
||||
Diese Aktion wird benutzt, um mit deinem Ritter zu schlagen. Es kann
|
||||
jeweils nur in eine Himmelsrichtung (0 für Norden, 1 für Osten, 2 für
|
||||
Süden und 3 für Westen) geschlagen werden und dies nur einen Block weit.
|
||||
Danach musst du 250 Millisekunden warten, bis du wieder angreifen
|
||||
kannst. Ein normaler Schlag, welcher mit einem Abstand von einem Block
|
||||
erzielt wurde, fügt dem Gegner weniger Schaden zu als wenn du auf
|
||||
demselben Block wie ein Gegner stehst. Hierbei ist es egal, wie viele
|
||||
Gegner auf einem Fleck stehen. Jeder bekommt gleich viel Schaden.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/hit/{direction}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/hit/{direction}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#hit>
|
||||
|
||||
|
||||
Shoot [POST]
|
||||
|
||||
|
||||
Shoot benötigt, wie Peek, eine Direction (0 für Norden, 1 für Osten, 2
|
||||
für Süden und 3 für Westen), also eine Richtung. Shoot verwendet diese
|
||||
Richtung, um einen Schuss in diese Richtung abzugeben. Als Antwort kommt
|
||||
zurück, ob diese Aktion ausgeführt wurde und ob ein Gegner getroffen
|
||||
wurde. Die Kugel stoppt beim ersten Spieler. Nachdem du diese Aktion
|
||||
verwendet hast, musst du 1000 Millisekunden warten.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/shoot/{direction}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/shoot/{direction}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#shoot>
|
||||
|
||||
|
||||
Radar [GET]
|
||||
|
||||
|
||||
Mit dem Befehl "Radar" kannst du die Umgebung um deinen Spieler im
|
||||
Umkreis von 5 Blöcken auf Feinde überprüfen. Das Feld wird aufgeteilt
|
||||
und durchsucht. Danach erhältst du Informationen über die Anzahl der
|
||||
Spieler in den 4 Himmelsrichtungen und den Block, auf dem du stehst.
|
||||
Nachdem du diese Aktion verwendet hast, musst du 250 Millisekunden warten.
|
||||
|
||||
Radar <https://dd.countit.at/media/dojo-game/dojo-game_radar-
|
||||
himmelsrichtungen.png>
|
||||
https://game-dd.countit.at/api/player/{key}/radar
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/radar
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#radar>
|
||||
|
||||
|
||||
Scan [GET]
|
||||
|
||||
|
||||
Mit Scan kannst du den am nächsten stehenden Spieler im Umkreis von 3
|
||||
Blöcken finden. Durch den Rückgabewert weißt du dann auch, was seine
|
||||
relative Position zu dir ist. Nachdem du diese Aktion verwendet hast,
|
||||
musst du 2000 Millisekunden warten.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/scan
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/scan
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request? <https://dd.countit.at/dojo-game/postman#scan>
|
||||
|
||||
|
||||
Peek [GET]
|
||||
|
||||
|
||||
Peek benötigt, wie Move und Hit, eine Direction (0 für Norden, 1 für
|
||||
Osten, 2 für Süden und 3 für Westen). Peek verwendet diese Richtung, um
|
||||
zu überprüfen, ob sich in der angegebenen Richtung ein Spieler in deinem
|
||||
Sichtfeld befindet. Peek gibt dir dann die Anzahl der Gegner in der
|
||||
Sichtlinie und die Distanz zum nächsten stehenden Spieler in dieser
|
||||
Sichtlinie zurück. Dies kannst du alle 1000 Millisekunden verwenden.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/peek/{direction}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/peek/{direction}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#peek>
|
||||
|
||||
|
||||
Stats [GET]
|
||||
|
||||
|
||||
Mit Stats hast du die Möglichkeit dir deine Kills und Deaths des aktiven
|
||||
Spiels anzusehen. Der Rückgabewert weicht vom Rückgabewert der anderen
|
||||
Funktionen ab - enthalten sind Informationen zum derzeitigen Level,
|
||||
allgemeine Stats sowie Informationen zu den Lebenspunkten eines Spielers.
|
||||
|
||||
*progress* - gibt an, wie weit du ein Level bereits abgeschlossen hast (%)
|
||||
*remainingtime* - gibt an, wieviele Minuten noch übrig sind bevor das
|
||||
Spiel gestoppt wird
|
||||
*deathsleft* - gibt an, wie oft du noch sterben darfst, bevor das Spiel
|
||||
gestoppt wird
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/stats
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/stats
|
||||
|
||||
Der Rückgabewert dieser Funktion wurde mit dem letzten Update verändert.
|
||||
Hier ein Beispiel für den neuen Rückgabewert:
|
||||
|
||||
{"action":"stats","executed":true,"stats":
|
||||
{"kills":1,"deaths":1},"level":
|
||||
{"progress":6.6,"remainingtime":14.44,"deathsleft":999,"levelid":2,"name":"Bigger Map Level"},"health":{"currenthealth":10.0,"maxhealth":10.0}}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
{"action":"stats","executed":true,"stats":{"kills":1,"deaths":1},"level":{"progress":6.6,"remainingtime":14.44,"deathsleft":999,"levelid":2,"name":"Bigger Map Level"},"health":{"currenthealth":10.0,"maxhealth":10.0}}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#stats>
|
||||
|
||||
|
||||
Specialattack [POST]
|
||||
|
||||
|
||||
Specialattack ist eine Aktion, welche du viel seltener als einen
|
||||
normalen Schlag ("Hit") einsetzen kannst. Diese hat allerdings eine
|
||||
bestimmte Fähigkeit und verursacht dadurch mehr Schaden an deinem
|
||||
Gegner. Specialattack nimmt keine Direction als Parameter entgegen,
|
||||
sondern führt den Angriff in allen Richtungen mit einem Wirkungskreis
|
||||
von 3 Blöcken gleichzeitig aus. Du kannst die Specialattack alle 5000
|
||||
Millisekunden ausführen.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/specialattack
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/specialattack
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#specialattack>
|
||||
|
||||
|
||||
Teleport [GET]
|
||||
|
||||
|
||||
Mit Teleport kannst du dich auf ein beliebiges Feld teleportieren. Der
|
||||
Trick dabei: Du musst das Feld relativ zu deiner Position mithilfe von x
|
||||
und y Koordinaten angeben.
|
||||
Cooldown: 20000 Millisekunden (20 Sekunden)
|
||||
|
||||
Achtung: Falls du in einer Wand landest bist du sofort tot. Wenn du
|
||||
allerdings einen Gegner erwischst, wird dieser sofort getötet.
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/teleport/{x}/{y}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
https://game-dd.countit.at/api/player/{key}/teleport/{x}/{y}
|
||||
|
||||
➯ Problem? <https://dd.countit.at/dojo-game/tipps#fehler>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#teleport>
|
||||
|
||||
|
||||
Rückgabewert
|
||||
|
||||
|
||||
Jede Aktion gibt im Prinzip immer einen gleich strukturierten JSON-
|
||||
String zurück. Jedoch können sich die Datentypen der einzelnen Felder je
|
||||
nach Aktion unterscheiden.
|
||||
Hier zwei Beispiele, um dies zu verdeutlichen:
|
||||
|
||||
Die Move-Aktion, ohne speziellen Rückgabewert:
|
||||
|
||||
{"action":"move","move":"true","executed":"true"}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
{"action":"move","move":"true","executed":"true"}
|
||||
|
||||
Die Radar-Aktion, mit einem Integer als Rückgabewert:
|
||||
|
||||
{"action":"radar","radar":2,"executed":"true"}
|
||||
text/x-csharp
|
||||
|
||||
xxxxxxxxxx
|
||||
|
||||
|
||||
|
||||
{"action":"radar","radar":2,"executed":"true"}
|
||||
|
||||
➯ Was ist JSON? <https://dd.countit.at/dojo-game/tipps#technologie>
|
||||
➯ Postman-Request <https://dd.countit.at/dojo-game/postman#rueckgabewerte>
|
||||
|
||||
|
||||
Bereit für die ultimative Programmier-Challenge an deiner Schule?
|
||||
|
||||
Alle Infos dazu findest du hier //
|
||||
<https://dd.countit.at/programmierwettbewerb>
|
||||
/
|
||||
|
||||
/
|
||||
|
||||
|
||||
Ultimative Coding-Roadmap
|
||||
|
||||
Unsere Roadmap weist dir den Weg zum Coding-Profi!
|
||||
|
||||
Mehr erfahren // <https://dd.countit.at/programmieren-lernen>
|
||||
/
|
||||
|
||||
/
|
||||
|
||||
|
||||
Besiege unseren Bot
|
||||
|
||||
Egal ob als Einzelspieler oder im Mulitplayer-Modus: Stelle dich dem
|
||||
Dojo-Bot und beweise, dass du auf das Leaderboard gehörst!
|
||||
|
||||
Ich bin bereit! // <https://dd.countit.at/dojo-game>
|
||||
/
|
||||
|
||||
/
|
||||
|
||||
|
||||
Bewerbung bei COUNT IT
|
||||
|
||||
Starte deine Karriere als Softwareentwickler*in bei COUNT IT.
|
||||
|
||||
Zum Formular! // <https://dd.countit.at/bewerben>
|
||||
|
||||
|
||||
Über Digital Dojo
|
||||
|
||||
Das Digital Dojo ist der virtuelle Übungsraum von COUNT IT.
|
||||
|
||||
Angehende Programmierer*innen, Code-Neulinge, Wiedereinsteiger*innen und
|
||||
Fortgeschrittene finden hier das nötige Rüstzeug für ihre Karriere.
|
||||
|
||||
Du möchtest deine Lehre bei COUNT IT starten? Dann bist du hier richtig
|
||||
- besiege deine Gegner im Dojo Game und sichere dir deine Lehrstelle!
|
||||
|
||||
Inspire your career.
|
||||
|
||||
|
||||
Navigation
|
||||
|
||||
Programmieren lernen <https://dd.countit.at/programmieren-lernen> News
|
||||
<https://dd.countit.at/news>
|
||||
Programmierschule <https://dd.countit.at/programmierschule> Partner
|
||||
<https://dd.countit.at/partner>
|
||||
Programmier-Challenge <https://dd.countit.at/programmierwettbewerb>
|
||||
Dojo Game <https://dd.countit.at/dojo-game>
|
||||
|
||||
|
||||
Datenschutz <https://www.countit.at/datenschutz> Karriere @ COUNT IT
|
||||
<https://karriere.countit.at/>
|
||||
Impressum <https://www.countit.at/impressum> COUNT IT
|
||||
Softwarehouse <https://it.countit.at/>
|
||||
|
||||
|
||||
Newsletter abonnieren
|
||||
|
||||
Der COUNT IT Newsletter liefert viermal jährlich interessante
|
||||
Neuigkeiten über das Unternehmen. Gleich anfordern!
|
||||
|
||||
E-Mail-Adresse
|
||||
Senden
|
||||
|
||||
// <https://de-de.facebook.com/COUNTITGroup/> // <https://
|
||||
www.instagram.com/count_it_group/> // <https://de.linkedin.com/company/
|
||||
count-it-group>
|
||||
|
||||
//
|
||||
|
||||
COUNT IT Group verwendet Cookies, um die Website bestmöglich an die
|
||||
Bedürfnisse der User anpassen zu können.
|
||||
|
||||
* Google
|
||||
* Microsoft
|
||||
* Ahrefs
|
||||
* Statistik
|
||||
|
||||
Akzeptieren
|
||||
Individuelle EinstellungenIndividuelle Einstellungen ausblenden |
|
||||
Datenschutzerklärung <https://www.countit.at/datenschutz>
|
||||
|
||||
Google
|
||||
|
||||
Google Analytics und Optimize aggregiert Daten über unsere Besucher und
|
||||
ihr Verhalten auf unserer Website. Wir nutzen diese Informationen zur
|
||||
Verbesserung unserer Seite.
|
||||
|
||||
Microsoft
|
||||
|
||||
Microsoft aggregiert Daten über unsere Besucher und ihr Verhalten auf
|
||||
unserer Website. Wir nutzen diese Informationen zur Verbesserung unserer
|
||||
Seite.
|
||||
|
||||
Ahrefs
|
||||
|
||||
Ahrefs aggregiert Daten über unsere Besucher und ihr Verhalten auf
|
||||
unserer Website. Wir nutzen diese Informationen zur Verbesserung unserer
|
||||
Seite.
|
||||
|
||||
Statistik
|
||||
|
||||
Es werden grundlegend notwendige, anonymisierte Userdaten aufgezeichnet,
|
||||
welche nur von uns für Auswertungen verwendet werden!
|
||||
|
||||
Cookie Entscheidung speichern
|
||||
Reference in New Issue
Block a user