Skip to content

Instantly share code, notes, and snippets.

@CyberShadow
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CyberShadow/f453322521bcf58ab586 to your computer and use it in GitHub Desktop.
Save CyberShadow/f453322521bcf58ab586 to your computer and use it in GitHub Desktop.
Golden Sun - Lucky Dice analysis
/analysis.txt
/rolls.txt
/*.png
/*.svg
/plot.gnu
*.exe
*.ilk
*.pdb
import std.algorithm;
import std.file;
import std.range;
import std.stdio;
import std.string;
void main()
{
enum bet = 230;
auto rolls = slurp!(int, int, int, int)("rolls.txt", "%d,%d,%d,%d\r");
static int height(int alt) { return (alt-32) / 4; }
static int alt(int height) { return 32 + height*4; }
enum heights = height(160) + 1;
int[heights] counts, winnings, r1, r2, re;
int[2][6][heights] throws;
foreach (ref roll; rolls)
{
auto h = height(roll[0]);
counts[h]++;
winnings[h] += roll[1];
r1[h] += roll[2];
r2[h] += roll[3];
re[h] += roll[2] == roll[3] ? 1 : 0;
throws[h][roll[2]][0]++;
throws[h][roll[3]][1]++;
}
writeln("Alt.\tSamples\tEarned\tLeft\tRight\tMatch %" ~ 6.iota.map!(n => "\t%d L %%\t%d R %%".format(n+1, n+1)).join());
foreach (h; 0..heights)
{
real n = counts[h];
writefln("%3d\t%d\t%3.3f\t%1.5f\t%1.5f\t%2.4f\t%(%2.4f\t%)",
alt(h),
counts[h],
winnings[h] / n / bet,
r1[h] / n + 1,
r2[h] / n + 1,
re[h] / n * 100,
//throws[h][].map!(t => t[].map!(c => c / n * 100)).join()
throws[h][].map!(t => [t[0] / n * 100, t[1] / n * 100]).join()
);
}
}
A_DiceLanded = 0x02003025
A_Cube1Altitude = 0x02037086 -- Left cube
A_Cube2Altitude = 0x020370A2 -- Right cube
A_Earnings = 0x03007C00
A_Cube1Area = 0x03007C98
A_Cube2Area = 0x03007C9C
f = io.open("C:\\Temp\\2014-09-16\\rolls.txt", "a")
while true do
height = 32 + math.random(0, 32) * 4 -- [32,160], increments of 4
--print "Mashing A to skip earnings"
while (memory.readbyte(A_DiceLanded) == 1) do
joypad.set(1, {A=1})
vba.frameadvance()
end
--print "Pre-throw delay"
for i=1,25 do
joypad.set(1, {A=1})
memory.writebyte(A_Cube1Altitude, height)
memory.writebyte(A_Cube2Altitude, height)
vba.frameadvance()
end
--print "Waiting for dice to land"
while (memory.readbyte(A_DiceLanded) == 0) do
vba.frameadvance()
end
--print "Dice landed, earnings:"
--print(height, memory.readword(A_Earnings), memory.readbyte(A_Cube1Area), memory.readbyte(A_Cube2Area))
f:write(height, ",", memory.readword(A_Earnings), ",", memory.readbyte(A_Cube1Area), ",", memory.readbyte(A_Cube2Area), "\n")
f:flush()
end
import std.conv;
import std.string;
import std.range;
import std.stdio;
import std.process;
File f;
void plot(string format)
{
enum w = 480, h = 320;
void reset(string name, string title)
{
f.writeln(`reset`);
f.writeln("set datafile separator \"\t\"");
f.writef (`set terminal %s size %d,%d`, format, w, h);
if (format=="svg") f.writef(` name "%s"`, name);
f.writeln();
f.writeln(`set output "` ~ name ~ `.` ~ format ~ `"`);
f.writeln(`set xlabel "Throw height`);
f.writeln(`set xrange [32:160]`);
f.writeln(`set xtics 32`);
f.writeln(`set xtics format "%1.0fpx"`);
f.writeln(`set ylabel "` ~ title ~ `"`);
}
reset("earnings", "Average earnings");
f.writeln(`set yrange [220:340]`);
f.writeln(`set ytics format "%g coins"`);
f.write (`plot "analysis.txt" using 1:3 title "Earned" with lines,`);
f.writeln(`230 title "Break even" with lines linecolor rgbcolor "#0000FF"`);
dstring dieFaces = 6.iota.map!(n => dchar('\u2680' + n)).array.idup;
reset("rolls", "Average landing zone");
f.writeln(`set yrange [1:6]`);
f.writeln(`set ytics (` ~ 6.iota.map!(n => `"%s" %d`.format(dieFaces[n], n+1)).join(`, `) ~ `)`);
f.writeln(`set ytics font ",30"`);
f.writeln(`plot for[col=4:5] "analysis.txt" using 1:col title columnheader(col) with lines`);
reset("matches", "Chance of landing in the same zone");
f.writeln(`set ytics format "%1.0f%%"`);
f.writeln(`plot for[col=6:6] "analysis.txt" using 1:col title columnheader(col) with lines`);
foreach (n; 0..6)
{
reset("land_%d".format(n+1), "Chance of landing on " ~ dieFaces[n].text);
f.writeln(`set ytics format "%1.0f%%"`);
f.writeln(`set yrange [0:60]`);
f.writefln(`set label 9999 "%s" at screen 0.54,0.52 center font ",128" textcolor rgbcolor "#CCCCCC"`, dieFaces[n]);
f.write (`plot "analysis.txt" using 1:` ~ (7+n*2).text ~ ` title "Left" with lines,`);
f.writeln(`"analysis.txt" using 1:` ~ (8+n*2).text ~ ` title "Right" with lines`);
}
}
int main()
{
f = File("plot.gnu", "wb");
plot("svg");
plot("png");
f.close();
return spawnProcess(["gnuplot.exe", f.name]).wait();
}
#!/bin/bash
set -ue
rdmd analyze > analysis.txt
rdmd plot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment