I don't know if this is a difficult question. Anyway here is an update of the program I use that should make it even clearer and simpler to see what I mean very precisely.
Code: Select all
'attempt of a custom random number generator
#include "fbgfx.bi"
'__________________________________here stand the definitions
#macro _SETWORKINGSCREENPAGEANDVISIBLESCREENPAGE(w, v)
screenSet (w), (v)
#endMacro
#macro _COPYWORKINGSCREENPAGETOVISIBLESCREENPAGE(w, v)
screenCopy (w), (v)
#endMacro
type BUTTON
declare constructor()
declare sub TriggerMouseTest()
declare sub DrawButton()
as integer _left
as integer _top
as integer _width
as integer _height
as string _text
as boolean _hasMouseOver
as boolean _hasMouseClick
as boolean _hasMouseButtonReleased
end type
constructor BUTTON
dim as integer scrW, scrH
screenInfo scrW, scrH
with THIS
._left => scrW\2 - 2
._top => scrH\2 - 2
._width => scrW\24
._height => scrH\24
._text => "default"
._hasMouseOver => FALSE
._hasMouseClick => FALSE
._hasMouseButtonReleased => FALSE
end with
end constructor
sub BUTTON.TriggerMouseTest()
dim as integer whereMouseX, _
whereMouseY, _
whatMouseButtonClicked
GetMouse whereMouseX, whereMouseY, , whatMouseButtonClicked
with THIS
if whereMouseX>=._left andAlso _
whereMouseX<(._left+ ._width) andAlso _
whereMouseY>=._top andAlso _
whereMouseY<(._top + ._height) then
if not ._hasMouseOver then
._hasMouseOver = TRUE
end if
else
if ._hasMouseOver then
._hasMouseOver = FALSE
end if
end if
'
if ._hasMouseOver andAlso cBool(whatMouseButtonClicked>0) then
if not ._hasMouseClick then
._hasMouseClick = TRUE
end if
else
if ._hasMouseClick then
._hasMouseClick = FALSE
if ._hasMouseOver then
if not ._hasMouseButtonReleased then
._hasMouseButtonReleased = TRUE
else
._hasMouseButtonReleased = FALSE
end if
end if
else
._hasMouseButtonReleased = FALSE
end if
end if
end with
end sub
sub BUTTON.DrawButton()
THIS.TriggerMouseTest()
'
dim as long btnColor
with THIS
if ._hasMouseButtonReleased then
btnColor = rgb(100,200,100)
elseIf ._hasMouseClick then
btnColor = rgb(100,100,200)
else
btnColor = rgb(100,100,100)
end if
'
line (._left,._top)- _
(._left + ._width - 1,._top + ._height - 1), _
btnColor, _
bf
end with
end sub
type DRAGGABLECIRCLE
declare constructor()
declare constructor(byval as integer, _
byval as integer, _
byval as integer, _
byval as ulong, _
byval as string)
declare destructor()
declare function AddDraggableCirclePtrToFamily() as integer
declare sub TestDraggablePointForMouse()
declare sub DrawDraggablePoint()
as single _x
as single _y
as single _radius
as ulong _color
as string _pointName
as boolean _mouseOver
as boolean _mouseClick
as boolean _dragStarted
as single _xAtDragtime
as single _yAtDragtime
'private:
as integer _draggableCircleFamilyMemberIndex
static as integer draggableCirclePtrFamilyMemberCount
static as DRAGGABLECIRCLE ptr familyArrayOfDraggableCirclePtr(any)
end type 'DRAGGABLECIRCLE
'static member initialization_
dim as integer DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount => -1
dim as DRAGGABLECIRCLE ptr DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr(any)
'member method implementation_
constructor DRAGGABLECIRCLE()
dim as integer scrW, scrH, scrD
if screenPtr()=0 then
scrW => 200
scrH => 200
scrD => 032
screenRes scrW, scrH, scrD
windowTitle "opened by DRAGGABLECIRCLE"
else
screenInfo scrW, scrH, scrD
end if
with THIS
._x => scrW\2
._y => scrH\2
._radius => 4
._color => iif(scrD=8, 14, rgb(200,200,0))
._pointName => "Default"
._mouseOver => FALSE
._mouseClick => FALSE
._dragStarted => FALSE
end with 'THIS
'
THIS._draggableCircleFamilyMemberIndex => THIS.AddDraggableCirclePtrToFamily()
'
end constructor 'DRAGGABLECIRCLE default constructor
constructor DRAGGABLECIRCLE(byval X as integer, _
byval Y as integer, _
byval Radius as integer, _
byval Colour as ulong, _
byval PointName as string)
with THIS
._x => X
._y => Y
._radius => Radius
._color => Colour
._pointName => PointName
._mouseOver => FALSE
._mouseClick => FALSE
._dragStarted => FALSE
end with 'THIS
'
THIS._draggableCircleFamilyMemberIndex => THIS.AddDraggableCirclePtrToFamily()
'
end constructor 'DRAGGABLECIRCLE(valINT,valINT,valINT,valULNG,valSTR)
destructor DRAGGABLECIRCLE()
if THIS._draggableCircleFamilyMemberIndex=-1 then exit destructor
'
select case DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount
case is>1
DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount -= 1
'
swap DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr( _
DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount - 1), _
DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr( _
THIS._draggableCircleFamilyMemberIndex)
'
redim preserve DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr( _
uBound(DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr) - 1)
'
for index as integer = 0 to uBound(DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr)
DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr(index)->_draggableCircleFamilyMemberIndex = _
index
next index
case else
DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount = 0
erase DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr
end select 'DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount
'
THIS._draggableCircleFamilyMemberIndex = -1
end destructor 'DRAGGABLECIRCLE default destructor
function DRAGGABLECIRCLE.AddDraggableCirclePtrToFamily() as integer
redim preserve DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr( _
uBound(DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr) + 1)
DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount = _
uBound(DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr) + 1
DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr( _
uBound(DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr) ) = @THIS
'---->
return DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount - 1
end function 'INT:=DRAGGABLECIRCLE.AddDraggableCirclePtrToFamily()
sub DRAGGABLECIRCLE.TestDraggablePointForMouse()
if THIS._draggableCircleFamilyMemberIndex=-1 then exit sub
'
dim as integer gmX, gmY, gmBtn1
getMouse gmX, gmY, , gmBtn1
'
if abs(gmX - THIS._x)<=THIS._radius and _
abs(gmY - THIS._y)<=THIS._radius then
if not THIS._mouseOver then THIS._mouseOver = TRUE
if gmBtn1=+1 then
if not THIS._mouseClick then
THIS._mouseClick = TRUE
dim as boolean otherFamillyMemberHasDragStarted => FALSE
for index as integer = 0 to DRAGGABLECIRCLE.draggableCirclePtrFamilyMemberCount - 1
if DRAGGABLECIRCLE.familyArrayOfDraggableCirclePtr(index)->_dragStarted then
otherFamillyMemberHasDragStarted = TRUE
exit for
end if
next index
if not otherFamillyMemberHasDragStarted then
THIS._dragStarted = TRUE
THIS._xAtDragtime = gmX
THIS._yAtDragtime = gmY
end if
end if
else
if THIS._mouseClick then
THIS._mouseClick = FALSE
THIS._dragStarted = FALSE
end if
end if
else
if THIS._mouseOver then THIS._mouseOver = FALSE
if THIS._mouseClick and not THIS._dragStarted then
THIS._mouseClick = FALSE
end if
end if
end sub 'DRAGGABLECIRCLE.TestDraggablePointForMouse()
sub DRAGGABLECIRCLE.DrawDraggablePoint()
dim as single constX => THIS._x
'
if THIS._draggableCircleFamilyMemberIndex=-1 then
exit sub
else
THIS.TestDraggablePointForMouse()
end if
'
circle (THIS._x,THIS._y), (THIS._radius + 1), THIS._color
draw string (THIS._x - 8 - (THIS._radius + 1), _
THIS._y - 8 - (THIS._radius + 1)), _
THIS._pointName, _
THIS._color
'
if THIS._mouseOver then
circle (THIS._x,THIS._y), THIS._radius - 1, rgb(0,255,0),,,,f
end if
if THIS._mouseClick then
circle (THIS._x,THIS._y), THIS._radius - 2, rgb(255,0,0),,,,f
end if
if THIS._dragStarted then
dim as integer gmX, gmY, gmBtn1
getMouse gmX, gmY, , gmBtn1
if gmX=-1 or gmY=-1 then exit sub
if ((gmX - THIS._x)^2 + (gmY - THIS._y)^2)>THIS._radius^2 then
setMouse ( THIS._x + 4*(gmX - THIS._x)/5 ), _
( THIS._y + 4*(gmY - THIS._y)/5 )
'this below lowers a little the mouse speed
THIS._x = THIS._x + 3*(gmX - THIS._x)/5
THIS._y = THIS._y + 3*(gmY - THIS._y)/5
else
THIS._x = gmX
THIS._y = gmY
setMouse gmX, gmY
end if
end if
'
THIS._x = constX
end sub 'DRAGGABLECIRCLE.DrawDraggablePoint()
type TWEAKABLEDISCREETREPARTITIONPANEL
declare constructor()
declare destructor()
declare property ProbabilityAtIndex(byval as integer) as single
declare property ProbabilitySum() as single
declare property RandomValue() as single
declare sub TestMouse()
declare sub DrawPanel()
declare function RandomNumberInTheDiscreetRepartion() as single
as integer _topLeftCornerX
as integer _topLeftCornerY
as integer _panelWidth
as integer _panelHeight
as DRAGGABLECIRCLE ptr _arrayOfDCptr(any)
end type
constructor TWEAKABLEDISCREETREPARTITIONPANEL()
if screenPtr()=0 then
screenRes 800, 600, 32
end if
'
dim as integer scrX, scrY
screenInfo scrX, scrY
'
with THIS
._topLeftCornerX => scrX\10
._topLeftCornerY => scrY\10
._panelWidth => scrX - 2*._topLeftCornerX
._panelHeight => scrY - 8*._topLeftCornerY
end with
'
redim ._arrayOfDCptr(0 to 63)
for index as integer = lBound(THIS._arrayOfDCptr) to uBound(THIS._arrayOfDCptr)
THIS._arrayOfDCptr(index) = new DRAGGABLECIRCLE
with *THIS._arrayOfDCptr(index)
._x => THIS._topLeftCornerX + index*THIS._panelWidth/(uBound(THIS._arrayOfDCptr) - lBound(THIS._arrayOfDCptr) + 1)
._y => THIS._topLeftCornerY + THIS._panelHeight - THIS._panelHeight/(uBound(THIS._arrayOfDCptr) - lBound(THIS._arrayOfDCptr) + 1)
._pointName => str(index)
end with
next index
end constructor
destructor TWEAKABLEDISCREETREPARTITIONPANEL()
for index as integer = lBound(THIS._arrayOfDCptr) to uBound(THIS._arrayOfDCptr)
delete THIS._arrayOfDCptr(index)
next index
end destructor
property TWEAKABLEDISCREETREPARTITIONPANEL.ProbabilityAtIndex(byval Index as integer) as single
'
if Index>=lBound(THIS._arrayOfDCptr) andAlso Index<=uBound(THIS._arrayOfDCptr) then
return (THIS._topLeftCornerY + THIS._panelHeight - THIS._arrayOfDCptr(index)->_y)/(THIS._panelHeight)
else
return 0
end if
end property
property TWEAKABLEDISCREETREPARTITIONPANEL.ProbabilitySum() as single
dim as single sum => 0
for index as integer = lBound(THIS._arrayOfDCptr) to uBound(THIS._arrayOfDCptr)
sum += THIS.ProbabilityAtIndex(index)
next index
return sum
end property
property TWEAKABLEDISCREETREPARTITIONPANEL.RandomValue() as single
'this should return a value according to its probability
return rnd()
end property
sub TWEAKABLEDISCREETREPARTITIONPANEL.TestMouse()
'
end sub
sub TWEAKABLEDISCREETREPARTITIONPANEL.DrawPanel()
THIS.TestMouse()
'
line (THIS._topLeftCornerX, THIS._topLeftCornerY)-step(THIS._panelWidth - 1,THIS._panelHeight - 1), rgb(100,120,100), bf
line (THIS._topLeftCornerX, THIS._topLeftCornerY)-step(THIS._panelWidth - 1 - 8,THIS._panelHeight - 1), rgb(100,120,190), bf
draw string (THIS._topLeftCornerX + THIS._panelWidth - 1 - 6, THIS._topLeftCornerY), str(1)
draw string (THIS._topLeftCornerX + THIS._panelWidth - 1 - 6, THIS._topLeftCornerY + THIS._panelHeight - 1 - 6), str(0)
for index as integer = lBound(THIS._arrayOfDCptr) to uBound(THIS._arrayOfDCptr)
if index=lBound(THIS._arrayOfDCptr) then
pReset (THIS._arrayOfDCptr(index)->_x, THIS._arrayOfDCptr(index)->_y)
else
line (THIS._arrayOfDCptr(index - 1)->_x, THIS._arrayOfDCptr(index - 1)->_y)-(THIS._arrayOfDCptr(index)->_x, THIS._arrayOfDCptr(index)->_y), rgb(100,200,200)
end if
THIS._arrayOfDCptr(index)->DrawDraggablePoint()
if THIS._arrayOfDCptr(index)->_y<THIS._topLeftCornerY then THIS._arrayOfDCptr(index)->_y = THIS._topLeftCornerY
if THIS._arrayOfDCptr(index)->_y>(THIS._topLeftCornerY + THIS._panelHeight) then
THIS._arrayOfDCptr(index)->_y = (THIS._topLeftCornerY + THIS._panelHeight)
end if
next index
end sub
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
screenRes 800, 500, 32, 2
dim as TWEAKABLEDISCREETREPARTITIONPANEL tdrp
dim as BUTTON generateBtn
generateBtn._left => 300
generateBtn._width => 200
dim as single randomValue => any
dim as single meanValueOther1000shots => 0
dim as integer shootCounter => 0
do
_SETWORKINGSCREENPAGEANDVISIBLESCREENPAGE(0, 1)
cls
generateBtn.DrawButton()
if generateBtn._hasMouseButtonReleased then shootCounter = 0
tdrp.DrawPanel()
draw string (94, 300), str("(no way to know if and what initialization is done by user for the randomizer)")
shootCounter += 1
randomValue = tdrp.RandomValue
if shootCounter<1000 then
meanValueOther1000shots = (shootCounter*meanValueOther1000shots + randomValue*64)/(shootCounter + 1)
else
shootCounter = 0
end if
draw string (300, 320), "instant value = " & str(randomValue), rgb(0,200,0)
draw string (340, 340), "mean = " & str(meanValueOther1000shots), rgb(200,200,0)
'show all the individual probabilities and the sum
for index as integer = lBound(tdrp._arrayOfDCptr) to uBound(tdrp._arrayOfDCptr)
draw string (40 + (index mod 7)*100, 360 + (index\7)*10), "p(" & str(index) & ") = " & left(str(tdrp.ProbabilityAtIndex(index)), 4)
next index
draw string (320, 480), "probability sum = " & str(tdrp.ProbabilitySum), rgb(200,200,0)
_COPYWORKINGSCREENPAGETOVISIBLESCREENPAGE(0, 1)
'
sleep 15
loop until inkey()=chr(27)
getKey()
'(eof)