From f2153d7e95a9b8ee99f540b27d53aca165a2f05c Mon Sep 17 00:00:00 2001 From: dkorpel Date: Tue, 21 Aug 2018 22:25:22 +0200 Subject: [PATCH] Add benchmarking --- docs/index.html | 7 ++++--- docs/tictac.wasm | Bin 17069 -> 19599 bytes source/app.d | 31 ++++++++++++++++++++++++++++--- source/draw.d | 6 +++++- source/game.d | 12 ++++++++++-- source/jsdraw.d | 9 ++++++--- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/docs/index.html b/docs/index.html index caffc0f..5d75439 100644 --- a/docs/index.html +++ b/docs/index.html @@ -60,8 +60,8 @@ } } -function _log(ptr, len) { - console.log(toJsString(ptr, len)); +function reportBenchmark(number, time) { + console.log("Evaluated "+number+" moves in "+time+" ms"); } function getTimeMillis() { @@ -118,7 +118,8 @@ drawCircle, setAlpha, setFont, - getTimeMillis + getTimeMillis, + reportBenchmark } }; diff --git a/docs/tictac.wasm b/docs/tictac.wasm index e30042fd0fb567a008989a0071056cb610e943a5..819c28a254dc50380513a92c874d438086cf0146 100644 GIT binary patch delta 6752 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 delta 4153 zcmb7HYit}>6~1?N_BFHXopqe7_vt%hJ5Sq*^CC5A>?=PakyJu;Xe4NrZ0sS~^}e#Z zb`pqKHxDF!v`u;oBB(8f{0eOm#6&7;iYg>Tkq`ojM*$&~KM~@k6j2HBkU8hh?s}cr zX<|z==iGbVbMD>qy>N}bahYB@a`mXC5prBPf1W5$d#*lfKJKg7Rh}!IN|S)gF3kC+ z%jq*u+EY~$Y_f+l1)H=XtKsfwraYCiNys(OFZ?uBqdu?KZ+NLY9QKFXy{em*D5Y)} zC5p#KYm~nuRNZ^YGvLYF`C|E;LOjPR)pWT^`n8jG^~rQ$x|rWbJON;il_fX0mw5fn zJ>qju<9a(KS7v>I1iUATXGc$^%OvQ|R7Oj)q)ptWy;=x8PL<9P zL;QtqJrvevOVjD9eK4K3Nqd{)D)TveB4g*K$+{pod@7yGOg~Yavn!+{Sjwf(+2teU zbGSg(`=?5?V?{}C5XY4SkF;Sq(AsFaFqf{7PCqU<=AurmX3LdgnZz`x@)LHYl0IpZ zI7S6LNr<ZPMkLcHFU$6FC2D)h^2b%<$AHdunEK zwq%#5>|E|>ra-KKT*G*f?GER`()e6DHw!sC7JGchj-@LV8*1OHW2}vsHUd{mpP96) z6U9Q6Y?8rGR?C^fNwOIWGYU>d?E?5GTYS~x9AvmnOXpzI>7+hi zrjV)1G7tDFRl6j~?XtHdxx-VoD^Phds7)0Mm1535Ts-L^JGIwy{fjedM2$xYBmB)T z&Ce75Q)*n9N5VTq-lY0oae7aOc-{BZV=v+=Q@D}s0cxJ;m)+D|Q$~~#M*E3tJh+w( zvDbgCT}Ty_RK|mDMvRxlAN_aem&LnUl72pWjavoUcac@jbir-n9y%*sGi zClD~+8psz?d+Arjt<>N3YiI!?rN-C9x4T}`Zm)OKns#2PQE`m*(+lD`mJeSAjN$cL;M{gIq_pB-Z z>s91$TKiY=y<}m`(eAZLpzHhA$n}KG*|F`Bi)eS}!;T$uo=e_@QKi?!D{Js70?-wq$3 zI{&Xj>P&|(kFNbITr(G^&X;%=^8@2y{yW);aOVV!3%JNMY#LBpfTxdt>)LB>Lw0dJ zUOdDo2TfILE-jdTMmfYux&L4guOHB$Wf@HE^dkDA>_Cs%uf?1GP+-Gh>Ia;eE% z?V&!^M=JY#hG0N<1+S2Qw?t94|iqZEX2^taJkN4C%q5oV3 zD+W5oE9ldTW2IE?%d*Zai)HcG&5D5mzC=&MPK?EefT3noXF(PP8c*Buzf?sfP_bfQ z3%5Ya03KQ#sP%PY6G5uifNw*|=)s`EVrCThby5<3w1Ew{b-9n;q8PzAC^?jsU?J3u z!&znt)&VpMOav7;(Q?a->nse*W)vbo|5gHXORzW!VlauCV+-jxcmu_DR7ipXhS5-v zuB8G?I!-7aRLsOmN!PfULhC6<0{Nu0D6^LyF;pl3N;#P(`O`9Da0|MS1wK+NAv1zn zq!=crvkkJ&a5uqMaRwW{UnaEy0)P+O0kT0!f-}uo)6A$~kMFNVIq4_gg^7+-;41@t z6KN*N@5p6L$ckmHIHz+gR$axmGTqTFe!fc#?JGD=6euUh6y zOZ#1?xvK;XFTbGES6+CjS@|&JJT+rQnfox5MPU(`x0s7jd__g%Kvyz?rzIj!3!EsG zzeDTuCv)pR6q5(iFo@kcFdkWB3>2~9T^+Ks^>!Rko5R}T^TUUf?ry^0yNb!I9DboZ zIR9ROsg*2#z&}sviy}YT1tZ*ZqjMn~34f%kgwOl*8@`uBci zcLjj+HSpU&G4FTqn^uQ!2;0(U0|?#r~|h!;I=Ij?Jc-%-950a zVa1RVNf!X#ZF5A(B NWrKB8wzCD4{U7Bh3<>}M diff --git a/source/app.d b/source/app.d index fc14749..02190c9 100644 --- a/source/app.d +++ b/source/app.d @@ -51,10 +51,16 @@ extern(C): } } - void _log(immutable(char)* ptr, size_t len); - - void consoleLog(string str) { + int getTimeMillis() @nogc; + void reportBenchmark(int number, int msecs) @nogc; + __gshared int benchmarkStartTime = 0; + void benchmarkStart() @nogc { + benchmarkStartTime = getTimeMillis(); + } + + void benchmarkEnd(int number) @nogc { + reportBenchmark(number, getTimeMillis()-benchmarkStartTime); } // These simple C standard library implementations are needed because @@ -144,4 +150,23 @@ extern(C): return result; } + + // Benchmark stuff + enum bool benchmarkShown = false; + long benchmarkMsecs = 0; + long benchmarkMoves = 0; + + import std.datetime.stopwatch: StopWatch, AutoStart; + private StopWatch stopWatch = StopWatch(AutoStart.no); + + void benchmarkStart() @nogc { + stopWatch.reset(); + stopWatch.start(); + } + + void benchmarkEnd(int movesAmount) @nogc { + stopWatch.stop(); + benchmarkMsecs = stopWatch.peek.total!"msecs"; + benchmarkMoves = movesAmount; + } } diff --git a/source/draw.d b/source/draw.d index 2cb271c..dced238 100644 --- a/source/draw.d +++ b/source/draw.d @@ -169,7 +169,11 @@ void drawMessage(in ref GameState state) { auto str = messageStrings[state.message]; int i = clamp(state.sinceLastMessage * 4, 0, cast(int) str.length); - window.write(1, 23, bgField, fgField, str[0..i]); //, str[0..$] + window.write(1, 23, bgField, fgField, str[0..i]); + + import app: benchmarkMoves, benchmarkMsecs, benchmarkShown; + if (benchmarkShown) + window.write(1, 24, bgField, fgField, "Evaluated ", benchmarkMoves, " moves in ", benchmarkMsecs, "ms"); } void drawTitleScreen(in ref GameState) { diff --git a/source/game.d b/source/game.d index 232b3d7..7dce71c 100644 --- a/source/game.d +++ b/source/game.d @@ -202,7 +202,7 @@ void updateGame(ref GameState state, Input input) { } break; case Mode.scramble: - if (globalTimer & 1) state.field.randomizeField(); + if ((globalTimer % 4) == 0) state.field.randomizeField(); if (input.enter) { field.getValidMoves(); @@ -358,9 +358,11 @@ void doMove(ref Field field, int x, int y) { Who winner = field.checkGameWin(); if (winner != Who.noone) { field.gameWon = winner; + field.validMoves = 0; + } else { + field.getValidMoves(); } - field.getValidMoves(); } // Cap amount of moves to prevent absurd waiting times for A.I. @@ -373,7 +375,13 @@ enum maxMovesConsidered = 3_000_000; void cpuDoMove(ref GameState state) { int x, y; totalMovesConsidered = 0; + + import app: benchmarkStart, benchmarkEnd; + + benchmarkStart(); bestMoveScore(state.field, state.cpuRecursionLevel, x, y); + benchmarkEnd(totalMovesConsidered); + state.field.doMove(x, y); state.updateAfterMove(); } diff --git a/source/jsdraw.d b/source/jsdraw.d index fbe0cca..82a5961 100644 --- a/source/jsdraw.d +++ b/source/jsdraw.d @@ -138,7 +138,7 @@ void drawField(in ref Field field, in ref WindowContext context, double anim = 1 drawLine(x, y+offset, x+edge, y+offset, innerThickness, fgColor); } - // Content and valid moves + // Content drawSetFont("30px Arial"); foreach(i; 0..9) foreach(j; 0..9) { auto str = field.fieldContent[i][j].toSymbol; @@ -148,18 +148,21 @@ void drawField(in ref Field field, in ref WindowContext context, double anim = 1 str.ptr, str.length, fgColor, ); + } + // Valid moves + if (field.gameWon == Who.noone) foreach(i; 0..9) foreach(j; 0..9) { if (field.validMove[i][j] == Validity.allowed) { // "Blink animation", going quickly to alpha 0.75 and slowly back to 0.25 if (anim > 0.5) setAlpha(1.25-anim); else if (anim > 0.25) setAlpha((anim-0.25)*3); else setAlpha(0); - + drawRect( x + i*cellEdge, y + j *cellEdge, cellEdge, cellEdge, allowedCellColor); - + setAlpha(1); } }