Allow tokens to be excluded from count with // #Debug

This commit is contained in:
Sebastian Lague 2023-07-29 13:31:56 +02:00
parent 282048c796
commit 4d5ea5d7ad
3 changed files with 67 additions and 33 deletions

View file

@ -23,7 +23,7 @@ namespace ChessChallenge.Application
}
// Game state
Random rng;
readonly Random rng;
int gameID;
bool isPlaying;
Board board;
@ -53,12 +53,13 @@ namespace ChessChallenge.Application
readonly BoardUI boardUI;
readonly MoveGenerator moveGenerator;
readonly int tokenCount;
readonly int debugTokenCount;
readonly StringBuilder pgns;
public ChallengeController()
{
Log($"Launching Chess-Challenge version {Settings.Version}");
tokenCount = GetTokenCount();
(tokenCount, debugTokenCount) = GetTokenCount();
Warmer.Warm();
rng = new Random();
@ -213,7 +214,7 @@ namespace ChessChallenge.Application
};
}
static int GetTokenCount()
static (int totalTokenCount, int debugTokenCount) GetTokenCount()
{
string path = Path.Combine(Directory.GetCurrentDirectory(), "src", "My Bot", "MyBot.cs");
@ -384,9 +385,10 @@ namespace ChessChallenge.Application
string nameB = GetPlayerName(PlayerBlack);
boardUI.DrawPlayerNames(nameW, nameB, PlayerWhite.TimeRemainingMs, PlayerBlack.TimeRemainingMs, isPlaying);
}
public void DrawOverlay()
{
BotBrainCapacityUI.Draw(tokenCount, MaxTokenCount);
BotBrainCapacityUI.Draw(tokenCount, debugTokenCount, MaxTokenCount);
MenuUI.DrawButtons(this);
MatchStatsUI.DrawMatchStats(this);
}

View file

@ -1,11 +1,17 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
using System.Collections.Generic;
using System.Linq;
using System;
namespace ChessChallenge.Application
{
public static class TokenCounter
{
// Including this in a comment will cause all tokens on the same line to be excluded from the count.
// Note: these tokens will still be counted in your final submission.
const string ignoreString = "#DEBUG";
static readonly HashSet<SyntaxKind> tokensToIgnore = new(new SyntaxKind[]
{
@ -20,40 +26,61 @@ namespace ChessChallenge.Application
SyntaxKind.CloseParenToken
});
public static int CountTokens(string code)
public static (int totalCount, int debugCount) CountTokens(string code)
{
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
SyntaxNode root = tree.GetRoot();
return CountTokens(root);
TextLineCollection lines = tree.GetText().Lines;
IEnumerable<SyntaxToken> allTokens = root.DescendantTokens();
// Total token count
int totalTokenCount = CountTokens(allTokens);
// Debug token count (tokens explicitly excluded by user for testing purposes)
var ignoreInstructions = root.DescendantTrivia().Where(t => IsIgnoreTokenInstruction(t));
int debugTokenCount = 0;
foreach(var ignore in ignoreInstructions)
{
int lineNumber = lines.GetLineFromPosition(ignore.SpanStart).LineNumber;
var debugTokens = allTokens.Where(t => lines.GetLineFromPosition(t.SpanStart).LineNumber == lineNumber);
debugTokenCount += CountTokens(debugTokens);
}
static int CountTokens(SyntaxNodeOrToken syntaxNode)
{
SyntaxKind kind = syntaxNode.Kind();
int numTokensInChildren = 0;
foreach (var child in syntaxNode.ChildNodesAndTokens())
{
numTokensInChildren += CountTokens(child);
return (totalTokenCount, debugTokenCount);
}
if (syntaxNode.IsToken && !tokensToIgnore.Contains(kind))
static int CountTokens(IEnumerable<SyntaxToken> tokens)
{
//Console.WriteLine(kind + " " + syntaxNode.ToString());
int tokenCount = 0;
foreach (var token in tokens)
{
tokenCount += GetTokenCountValue(token);
}
return tokenCount;
}
static int GetTokenCountValue(SyntaxToken token)
{
SyntaxKind kind = token.Kind();
if (tokensToIgnore.Contains(kind))
{
return 0;
}
// String literals count for as many chars as are in the string
if (kind is SyntaxKind.StringLiteralToken or SyntaxKind.InterpolatedStringTextToken)
{
return syntaxNode.ToString().Length;
return token.ToString().Length;
}
// Regular tokens count as just one token
return 1;
}
return numTokensInChildren;
}
static bool IsIgnoreTokenInstruction(SyntaxTrivia trivia)
{
var compareType = StringComparison.InvariantCultureIgnoreCase;
return trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) && trivia.ToString().Contains(ignoreString, compareType);
}
}
}

View file

@ -10,8 +10,9 @@ namespace ChessChallenge.Application
static readonly Color red = new(219, 9, 9, 255);
static readonly Color background = new Color(40, 40, 40, 255);
public static void Draw(int numTokens, int tokenLimit)
public static void Draw(int totalTokenCount, int debugTokenCount, int tokenLimit)
{
int activeTokenCount = totalTokenCount - debugTokenCount;
int screenWidth = Raylib.GetScreenWidth();
int screenHeight = Raylib.GetScreenHeight();
@ -20,7 +21,7 @@ namespace ChessChallenge.Application
// Bg
Raylib.DrawRectangle(0, screenHeight - height, screenWidth, height, background);
// Bar
double t = (double)numTokens / tokenLimit;
double t = (double)activeTokenCount / tokenLimit;
Color col;
if (t <= 0.7)
@ -34,11 +35,15 @@ namespace ChessChallenge.Application
Raylib.DrawRectangle(0, screenHeight - height, (int)(screenWidth * t), height, col);
var textPos = new System.Numerics.Vector2(screenWidth / 2, screenHeight - height / 2);
string text = $"Bot Brain Capacity: {numTokens}/{tokenLimit}";
if (numTokens > tokenLimit)
string text = $"Bot Brain Capacity: {activeTokenCount}/{tokenLimit}";
if (activeTokenCount > tokenLimit)
{
text += " [LIMIT EXCEEDED]";
}
else if (debugTokenCount != 0)
{
text += $" ({totalTokenCount} with Debugs included)";
}
UIHelper.DrawText(text, textPos, fontSize, 1, Color.WHITE, UIHelper.AlignH.Centre);
}
}