📄 gd22-01.cpp
字号:
// ============================================================================
// GD22-01.cpp
// Graphical Demonstration - Random Distributions
// ============================================================================
#include "SDLGUI.h"
#include <stdlib.h>
#include <time.h>
#include "RandomNumbers.h"
#include "Array.h"
// ============================================================================
// Global Constants
// ============================================================================
const char PROGRAM_NAME[] = "Graphical Demonstration 22-01 - Random Distributions";
const int WIDTH = 800;
const int HEIGHT = 600;
const int ITEMS = 128;
// ============================================================================
// Global Variables
// ============================================================================
SDLGUI* g_gui;
const int ARIAL = 0;
const int SMALLARIAL = 1;
const int BIGARIAL = 2;
char g_min1string[16] = "1";
char g_max1string[16] = "6";
char g_min2string[16] = "0";
char g_max2string[16] = "0";
char g_min3string[16] = "0";
char g_max3string[16] = "0";
char g_min4string[16] = "0";
char g_max4string[16] = "0";
int g_min1 = 1;
int g_max1 = 6;
int g_min2 = 0;
int g_max2 = 0;
int g_min3 = 0;
int g_max3 = 0;
int g_min4 = 0;
int g_max4 = 0;
int g_min;
int g_max;
int g_difference;
int g_outcomes;
// frequency tables
Array<int> g_theoreticalf( 1024 );
Array<int> g_actualf( 1024 );
// normalised frequency tables.
Array<float> g_theoreticalfn( 1024 );
Array<float> g_actualfn( 1024 );
bool g_theoreticalon = false;
bool g_actualon = false;
int g_trials = 1000;
char g_trialstring[16] = "1000";
char g_currentstring[16] = "0";
int g_current = 0;
char g_theoreticalstring[64] = "";
char g_actualstring[64] = "";
SDL_Surface* g_graph;
// ============================================================================
// Functions
// ============================================================================
void Normalise( Array<int>& p_table, Array<float>& p_normals, int p_count )
{
int i;
for( i = 0; i < p_table.Size(); i++ )
{
p_normals[i] = (float)(p_table[i]) / (float)p_count;
}
}
template <class T>
void swap( T& l, T& r )
{
T temp = l;
l = r;
r = temp;
}
void DrawGraph()
{
float ymax = 0;
int i;
int x;
float xmultiplier = 600.0f / (float)g_difference;
// new x and y
float nx, ny;
// previous x and y
float px, py;
for( i = 0; i < g_difference; i++ )
{
if( g_theoreticalfn[i] > ymax )
ymax = g_theoreticalfn[i];
if( g_actualfn[i] > ymax )
ymax = g_actualfn[i];
}
// clear the graph.
SDL_FillRect( g_graph, NULL, SDL_MapRGB( g_graph->format, 255, 255, 255 ) );
if( g_theoreticalon == true )
{
px = 50;
py = 500 - ((g_theoreticalfn[0] / ymax) * 450);
for( x = 1; x < g_difference; x++ )
{
nx = ((float)x * xmultiplier) + 50;
ny = 500 - ((g_theoreticalfn[x] / ymax) * 450);
SDLLine( g_graph, (int)px, (int)py, (int)nx, (int)ny, BLUE );
px = nx;
py = ny;
}
}
if( g_actualon == true )
{
px = 50;
py = 500 - ((g_actualfn[0] / ymax) * 450);
for( x = 1; x < g_difference; x++ )
{
nx = ((float)x * xmultiplier) + 50;
ny = 500 - ((g_actualfn[x] / ymax) * 450);
SDLLine( g_graph, (int)px, (int)py, (int)nx, (int)ny, RED );
px = nx;
py = ny;
}
}
// update the graph
SDL_UpdateRect( g_graph, 0, 0, 0, 0 );
}
// ============================================================================
// Callbacks
// ============================================================================
void calculate()
{
// find the mins and maxs.
// die 1.
g_min1 = atoi( g_min1string );
g_max1 = atoi( g_max1string );
if( g_min1 > g_max1 )
swap( g_min1, g_max1 );
sprintf( g_min1string, "%d", g_min1 );
sprintf( g_max1string, "%d", g_max1 );
// die 2
g_min2 = atoi( g_min2string );
g_max2 = atoi( g_max2string );
if( g_min2 > g_max2 )
swap( g_min2, g_max2 );
sprintf( g_min2string, "%d", g_min2 );
sprintf( g_max2string, "%d", g_max2 );
// die 3
g_min3 = atoi( g_min3string );
g_max3 = atoi( g_max3string );
if( g_min3 > g_max3 )
swap( g_min3, g_max3 );
sprintf( g_min3string, "%d", g_min3 );
sprintf( g_max3string, "%d", g_max3 );
// die 4
g_min4 = atoi( g_min4string );
g_max4 = atoi( g_max4string );
if( g_min4 > g_max4 )
swap( g_min4, g_max4 );
sprintf( g_min4string, "%d", g_min4 );
sprintf( g_max4string, "%d", g_max4 );
g_min = g_min1 + g_min2 + g_min3 + g_min4;
g_max = g_max1 + g_max2 + g_max3 + g_max4;
g_difference = g_max - g_min + 1;
// if the array isn't large enough to hold all the possible
// values, then resize them.
if( g_difference > g_theoreticalf.Size() )
{
g_theoreticalf.Resize( g_difference );
g_actualf.Resize( g_difference );
g_theoreticalfn.Resize( g_difference );
g_actualfn.Resize( g_difference );
}
g_outcomes = (g_max1 - g_min1 + 1) *
(g_max2 - g_min2 + 1) *
(g_max3 - g_min3 + 1) *
(g_max4 - g_min4 +1);
// convert the trials to a number. If invalid, set to 1,
// and write it back to the textbox.
g_trials = atoi( g_trialstring );
if( g_trials <= 0 )
{
g_trials = 1;
}
sprintf( g_trialstring, "%d", g_trials );
int a, b, c, d;
// clear the frequency tables
for( a = 0; a < g_difference; a++ )
{
g_theoreticalf[a] = 0;
g_actualf[a] = 0;
}
// fill the theoretical frequency table.
for( a = g_min1; a <= g_max1; a++ )
{
for( b = g_min2; b <= g_max2; b++ )
{
for( c = g_min3; c <= g_max3; c++ )
{
for( d = g_min4; d <= g_max4; d++ )
{
g_theoreticalf[(a+b+c+d) - g_min]++;
}
}
}
}
for( a = 0; a < g_trials; a++ )
{
b = RandomRange( g_min1, g_max1 );
b += RandomRange( g_min2, g_max2 );
b += RandomRange( g_min3, g_max3 );
b += RandomRange( g_min4, g_max4 );
g_actualf[b - g_min]++;
}
// normalise the tables.
Normalise( g_theoreticalf, g_theoreticalfn, g_outcomes );
Normalise( g_actualf, g_actualfn, g_trials );
if( g_current > g_max )
g_current = g_max;
if( g_current < g_min )
g_current = g_min;
sprintf( g_currentstring, "%d", g_current );
DrawGraph();
}
void TheoreticalToggle()
{
g_theoreticalon = !g_theoreticalon;
DrawGraph();
}
void ActualToggle()
{
g_actualon = !g_actualon;
DrawGraph();
}
void CurrentDown()
{
if( g_current > g_min )
g_current--;
sprintf( g_currentstring, "%d", g_current );
}
void CurrentUp()
{
if( g_current < g_max )
g_current++;
sprintf( g_currentstring, "%d", g_current );
}
int main( int argc, char* argv[] )
{
srand( time( 0 ) );
// declare coordinates.
int x, y;
// declare event holder
SDL_Event event;
// set our at exit function
atexit( SDL_Quit );
//initialize systems
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
TTF_Init();
SDL_EnableUNICODE( true );
// create the GUI and set the caption.
g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
SDL_WM_SetCaption( PROGRAM_NAME, 0);
// load the fonts
g_gui->SetFont( "arial.ttf", ARIAL, 17, TTF_STYLE_NORMAL );
g_gui->SetFont( "arial.ttf", SMALLARIAL, 12, TTF_STYLE_NORMAL );
g_gui->SetFont( "arial.ttf", BIGARIAL, 24, TTF_STYLE_NORMAL );
// add the 4 random ranges
// range 1
g_gui->AddLabel( 5, 10, "Range 1", BIGARIAL, BLACK, WHITE );
// min1
g_gui->AddLabel( 10, 40, "min", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 5, 60, 40, 20, g_min1string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// max1
g_gui->AddLabel( 55, 40, "max", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 50, 60, 40, 20, g_max1string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// range 2
g_gui->AddLabel( 5, 110, "Range 2", BIGARIAL, BLACK, WHITE );
// min2
g_gui->AddLabel( 10, 140, "min", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 5, 160, 40, 20, g_min2string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// max2
g_gui->AddLabel( 55, 140, "max", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 50, 160, 40, 20, g_max2string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// range 3
g_gui->AddLabel( 5, 210, "Range 3", BIGARIAL, BLACK, WHITE );
// min3
g_gui->AddLabel( 10, 240, "min", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 5, 260, 40, 20, g_min3string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// max3
g_gui->AddLabel( 55, 240, "max", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 50, 260, 40, 20, g_max3string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// range 4
g_gui->AddLabel( 5, 310, "Range 4", BIGARIAL, BLACK, WHITE );
// min4
g_gui->AddLabel( 10, 340, "min", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 5, 360, 40, 20, g_min4string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// max4
g_gui->AddLabel( 55, 340, "max", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 50, 360, 40, 20, g_max4string, 6, ARIAL,
BLACK, WHITE, true, calculate );
// calculate button
g_gui->AddButton( 0, 550, "ovalbuttonblue.bmp", "ovalbuttonblue.bmp",
"Calculate", ARIAL, BLACK, BLACK, calculate );
// the checkboxes
g_gui->AddCheckbox( 120, 520, "checkboxup.bmp", "checkboxdown.bmp",
"Theoretical Distribution", ARIAL, BLUE, WHITE,
TheoreticalToggle );
g_gui->AddCheckbox( 120, 550, "checkboxup.bmp", "checkboxdown.bmp",
"Actual Distribution", ARIAL, RED, WHITE,
ActualToggle );
// the number of trials.
g_gui->AddLabel( 400, 500, "Random Trials", ARIAL, BLACK, WHITE );
g_gui->AddTextBox( 400, 520, 80, 20, g_trialstring, 6, ARIAL,
BLACK, WHITE, true, calculate );
// the current sample buttons/labels.
g_gui->AddLabel( 400, 550, "Current:", ARIAL, BLACK, WHITE );
g_gui->AddButton( 400, 570, "littlebuttongrey-up.bmp", "littlebuttongrey-down.bmp",
"<", SMALLARIAL, BLACK, BLACK, CurrentDown );
g_gui->AddButton( 460, 570, "littlebuttongrey-up.bmp", "littlebuttongrey-down.bmp",
">", SMALLARIAL, BLACK, BLACK, CurrentUp );
g_gui->AddTextBox( 420, 570, 40, 20, g_currentstring, 6, ARIAL,
BLACK, WHITE, false, 0 );
g_gui->AddTextBox( 550, 520, 200, 20, g_theoreticalstring, 64, ARIAL,
BLACK, WHITE, false, 0 );
g_gui->AddTextBox( 550, 550, 200, 20, g_actualstring, 64, ARIAL,
BLACK, WHITE, false, 0 );
// create the graph bitmap
SDL_PixelFormat* pix = SDL_GetVideoInfo()->vfmt;
g_graph = SDL_CreateRGBSurface( 0, 700, 500, pix->BitsPerPixel,
pix->Rmask, pix->Gmask, pix->Bmask, pix->Amask );
calculate();
// main message loop.
while( 1 )
{
//look for an event
if( SDL_PollEvent( &event ) )
{
//an event was found
if( event.type == SDL_QUIT )
break;
if( event.type == SDL_MOUSEBUTTONDOWN )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
// tell the GUI that a button has been pressed
g_gui->MouseDown( x, y );
}
if( event.type == SDL_MOUSEBUTTONUP )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
// tell the GUI that a button has been released
g_gui->MouseUp( x, y );
}
if( event.type == SDL_KEYDOWN )
{
// a key was pressed.
if( event.key.keysym.sym == SDLK_ESCAPE )
{
// if ESC was pressed, quit the program.
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent( &quit );
}
// tell the GUI that a key was pressed.
g_gui->KeyDown( event.key.keysym.sym,
event.key.keysym.mod,
event.key.keysym.unicode );
}
// only redraw when an event occurs.
// create the percentage strings.
sprintf( g_theoreticalstring, "Theoretical: %f%%",
g_theoreticalfn[g_current - g_min] * 100.0f );
sprintf( g_actualstring, "Actual: %f%%",
g_actualfn[g_current - g_min] * 100.0f );
g_gui->Draw();
g_gui->Blit( g_graph, 100, 0 );
g_gui->Line( 100, 0, 100, 600, GREY );
g_gui->Line( 101, 0, 101, 600, BLACK );
g_gui->Line( 100, 500, 800, 500, GREY );
g_gui->Line( 100, 501, 800, 501, BLACK );
x = (int)((float)(g_current - g_min) * (600.0f / (float)g_difference)) + 150;
g_gui->Line( x, 0, x, 500, BLACK );
// tell the GUI to update itself
g_gui->Update();
} // end event loop.
}
// done
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -