これは、確率から統計的な確率を生成するプログラムですのソースコードです。
「確率通りになるまでの試行回数、パチンコ・パチスロ・投資の統計的確率」で使用しています。
/*
実行には、別途メルセンヌ・ツイスタ ライブラリが必要です。
次のファイル必須
SFMT-alti.h
SFMT-common.h
SFMT-neon.h
SFMT-params.h
SFMT-params11213.h
SFMT-params1279.h
SFMT-params132049.h
SFMT-params19937.h
SFMT-params216091.h
SFMT-params2281.h
SFMT-params4253.h
SFMT-params44497.h
SFMT-params607.h
SFMT-params86243.h
SFMT-sse2-msc.h
SFMT-sse2.h
SFMT.c
SFMT.h
*/
#include
#include "SFMT.h"
HINSTANCE s_hInstanceHandle =NULL;
LPSTR s_lpWindowClassName ="SimpleWindow2020";
// 1/300で195が出たらBIGに当選。
LPSTR s_lpBigDenominator="300";
// 1/200で188が出たらREGに当選。
LPSTR s_lpRegDenominator="200";
// 試行回数
LPSTR s_lpNumTry="10000";
typedef struct __BONUS{
DWORD dwNumBonus;
DWORD dwDenominator, dwMolecules;
}BONUS, *LPBONUS;
#define ID_ADD 100
#define ID_CLEAR 101
#define ID_COPY 102
#define ID_BIG 103
#define ID_REG 104
#define ID_TRY 105
#define ID_EDIT 106
// dwDenominator: 分母
// dwMolecules: 分子
inline void InitBonus(LPBONUS lpBonus, DWORD dwDenominator, DWORD dwMolecules)
{
lpBonus->dwNumBonus =0;
lpBonus->dwDenominator =dwDenominator;
lpBonus->dwMolecules =dwMolecules;
}
inline BOOL LoteryBonus(LPBONUS lpBonus, DWORD dwLottery)
{
if((dwLottery%
lpBonus->dwDenominator)==lpBonus->dwMolecules)
{
lpBonus->dwNumBonus++;
return TRUE; // 当選
}
return FALSE;
}
typedef struct __DATA{
BONUS big;
BONUS reg;
}DATA, *LPDATA;
typedef struct __SIMPLEWINDOWINFO{
HWND hWnd;
HWND hAdd;
HWND hCopy;
HWND hClear;
HWND hBig;
HWND hReg;
HWND hTry;
HWND hEdit;
LPDATA lpData;
DWORD dwNumData;
LPSTR lpTextBuffer;
LPBYTE lpBuffer;
}SIMPLEWINDOWINFO, *LPSIMPLEWINDOWINFO;
#define MAXDATA 1000
#define MAXTEXTBUFFER MAXDATA*200
HRESULT AllocAllData(LPSIMPLEWINDOWINFO lpInfo)
{
DWORD dwDataSize;
dwDataSize=MAXDATA*sizeof(DATA);
lpInfo->lpBuffer=new BYTE[dwDataSize+MAXTEXTBUFFER];
if(lpInfo->lpBuffer==NULL)
return E_OUTOFMEMORY;
LPBYTE lpBuffer;
lpBuffer=lpInfo->lpBuffer;
lpInfo->lpData =(LPDATA)lpBuffer;
lpBuffer+=dwDataSize;
lpInfo->lpTextBuffer=(LPSTR)lpBuffer;
return S_OK;
}
HRESULT FreeAllData(LPSIMPLEWINDOWINFO lpInfo)
{
if(lpInfo->lpBuffer!=NULL)
{
delete lpInfo->lpBuffer;
lpInfo->lpBuffer=NULL;
}
lpInfo->lpData =NULL;
lpInfo->lpTextBuffer =NULL;
return S_OK;
}
HRESULT DestroyClientWindows(LPSIMPLEWINDOWINFO lpInfo)
{
if(lpInfo->hAdd!=NULL)
{
DestroyWindow(lpInfo->hAdd);
}
if(lpInfo->hCopy!=NULL)
{
DestroyWindow(lpInfo->hCopy);
}
if(lpInfo->hClear!=NULL)
{
DestroyWindow(lpInfo->hClear);
}
if(lpInfo->hBig!=NULL)
{
DestroyWindow(lpInfo->hBig);
}
if(lpInfo->hReg!=NULL)
{
DestroyWindow(lpInfo->hReg);
}
if(lpInfo->hTry!=NULL)
{
DestroyWindow(lpInfo->hTry);
}
if(lpInfo->hEdit!=NULL)
{
DestroyWindow(lpInfo->hEdit);
}
ZeroMemory(lpInfo, sizeof(*lpInfo));
return S_OK;
}
HRESULT AddData(HWND hWnd, LPSIMPLEWINDOWINFO lpInfo)
{
if(lpInfo->dwNumData>=MAXDATA)
{
return E_FAIL;
}
LONG lBig, lReg, lTry;
lBig=GetDlgItemInt(hWnd, ID_BIG, NULL, NULL);
lReg=GetDlgItemInt(hWnd, ID_REG, NULL, NULL);
lTry=GetDlgItemInt(hWnd, ID_TRY, NULL, NULL);
if(lBig<1)
lBig=1;
if(lReg<1)
lReg=1;
if(lTry<1)
lTry=1;
sfmt_t sfmt;
sfmt_init_gen_rand(&sfmt, GetTickCount());
LONG i;
DWORD lottery;
BONUS big, reg;
InitBonus(&big, lBig, lBig*2/7);
InitBonus(®, lReg, lReg*3/4);
for(i=0; i<lTry; i++) { lottery=(DWORD)sfmt_genrand_uint32(&sfmt); if(LoteryBonus(&big, lottery) || LoteryBonus(®, lottery)) {// ボーナスを同時に当選しない continue; } } CopyMemory(&lpInfo->lpData[lpInfo->dwNumData].big, &big, sizeof(big));
CopyMemory(&lpInfo->lpData[lpInfo->dwNumData].reg, ®, sizeof(reg));
lpInfo->dwNumData++;
// ----- reset
LPSTR lpTextBuffer;
DWORD dwNumData, dwNumBigs, dwNumRegs;
LPDATA lpData;
lpTextBuffer=lpInfo->lpTextBuffer;
dwNumData =lpInfo->dwNumData;
lpData =lpInfo->lpData;
wsprintf(lpTextBuffer
, "回数 %d\r\n"
"総試行回数 %d\r\n"
, dwNumData
, lTry*dwNumData
);
lpTextBuffer+=strlen(lpTextBuffer);
dwNumBigs =0;
dwNumRegs =0;
strcpy(lpTextBuffer, "----- 各当選数 -----\r\n"
"BIG=");
lpTextBuffer+=strlen(lpTextBuffer);
for(i=0; i<(LONG)dwNumData; i++)
{
dwNumBigs +=lpData[i].big.dwNumBonus;
if(i)
wsprintf(lpTextBuffer, ", %d", lpData[i].big.dwNumBonus);
else
wsprintf(lpTextBuffer, "%d", lpData[i].big.dwNumBonus);
lpTextBuffer+=strlen(lpTextBuffer);
}
strcpy(lpTextBuffer, "\r\nREG=");
lpTextBuffer+=strlen(lpTextBuffer);
for(i=0; i<(LONG)dwNumData; i++) { dwNumRegs +=lpData[i].reg.dwNumBonus; if(i) wsprintf(lpTextBuffer, ", %d", lpData[i].reg.dwNumBonus); else wsprintf(lpTextBuffer, "%d", lpData[i].reg.dwNumBonus); lpTextBuffer+=strlen(lpTextBuffer); } strcpy(lpTextBuffer, "\r\n"); lpTextBuffer+=strlen(lpTextBuffer); DWORD dwBigDenominator, dwRegDenominator; DWORD dwBigMolecules, dwRegMolecules; if(dwNumBigs>0)
{
dwBigDenominator =lTry*dwNumData/dwNumBigs;
dwBigMolecules =1;
}
else
{
dwBigDenominator =lTry;
dwBigMolecules =0;
}
if(dwNumRegs>0)
{
dwRegDenominator =lTry*dwNumData/dwNumRegs;
dwRegMolecules =1;
}
else
{
dwRegDenominator =lTry;
dwRegMolecules =0;
}
wsprintf(lpTextBuffer
, "----- 合計 -----\r\n"
"BIG=%d\r\n"
"REG=%d\r\n"
"----- 試行による統計的確率 -----\r\n"
"BIG=%d/%d\r\n"
"REG=%d/%d\r\n"
, dwNumBigs
, dwNumRegs
, dwBigMolecules
, dwBigDenominator
, dwRegMolecules
, dwRegDenominator
);
lpTextBuffer+=strlen(lpTextBuffer);
::SetWindowText(lpInfo->hEdit, lpInfo->lpTextBuffer);
return S_OK;
}
void ClearData(LPSIMPLEWINDOWINFO lpInfo)
{
lpInfo->dwNumData=0;
if(lpInfo->hEdit!=NULL)
::SetWindowText(lpInfo->hEdit,"");
}
// ウィンドウプロシージャ
LRESULT CALLBACK LoterryWndProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
LPSIMPLEWINDOWINFO lpInfo;
lpInfo=(LPSIMPLEWINDOWINFO)GetWindowLongPtr(hWnd, 0);
if(lpInfo==NULL
|| lpInfo->hWnd==NULL)
{
switch(nMessage){
case WM_CREATE:
{
LPCREATESTRUCT lpcs=(LPCREATESTRUCT)lParam;
lpInfo=(LPSIMPLEWINDOWINFO)lpcs->lpCreateParams;
if(lpInfo==NULL)
return -1;
SetWindowLongPtr(hWnd, 0, (LONG_PTR)lpInfo); // こちらの方が将来的に安全
lpInfo->hWnd=hWnd;
if(DefWindowProc(hWnd, nMessage, wParam, lParam)!=0)
{
DestroyClientWindows(lpInfo);
return -1;
}
RECT rClient;
GetClientRect(hWnd, &rClient);
lpInfo->hAdd=CreateWindowEx(
0, "BUTTON", "Add"
, WS_VISIBLE|WS_CHILD| BS_PUSHBUTTON
, 0, 0, 100, 32, hWnd
, (HMENU)ID_ADD, s_hInstanceHandle, NULL);
lpInfo->hCopy=CreateWindowEx(
0, "BUTTON", "Copy"
, WS_VISIBLE|WS_CHILD| BS_PUSHBUTTON
, 100, 0, 100, 32, hWnd
, (HMENU)ID_COPY, s_hInstanceHandle, NULL);
lpInfo->hClear=CreateWindowEx(
0, "BUTTON", "Clear"
, WS_VISIBLE|WS_CHILD| BS_PUSHBUTTON
, 200, 0, 100, 32, hWnd
, (HMENU)ID_CLEAR, s_hInstanceHandle, NULL);
lpInfo->hBig=CreateWindowEx(
WS_EX_CLIENTEDGE, "EDIT", s_lpBigDenominator
, WS_VISIBLE|WS_CHILD| ES_NUMBER
, 300, 0, 100, 32, hWnd
, (HMENU)ID_BIG, s_hInstanceHandle, NULL);
lpInfo->hReg=CreateWindowEx(
WS_EX_CLIENTEDGE, "EDIT", s_lpRegDenominator
, WS_VISIBLE|WS_CHILD| ES_NUMBER
, 400, 0, 100, 32, hWnd
, (HMENU)ID_REG, s_hInstanceHandle, NULL);
lpInfo->hTry=CreateWindowEx(
WS_EX_CLIENTEDGE, "EDIT", s_lpNumTry
, WS_VISIBLE|WS_CHILD| ES_NUMBER
, 500, 0, 100, 32, hWnd
, (HMENU)ID_TRY, s_hInstanceHandle, NULL);
rClient.top+=32;
lpInfo->hEdit=CreateWindowEx(
WS_EX_CLIENTEDGE, "EDIT", NULL
, WS_VISIBLE|WS_CHILD| ES_MULTILINE| ES_WANTRETURN| ES_AUTOHSCROLL| ES_AUTOVSCROLL| WS_HSCROLL| WS_VSCROLL
, rClient.left, rClient.top, rClient.right-rClient.left, rClient.bottom-rClient.top, hWnd
, (HMENU)ID_EDIT, s_hInstanceHandle, NULL);
RECT rWindow;
LONG cx, cy;
GetWindowRect(hWnd, &rWindow);
cx=rWindow.right-rWindow.left;
cy=rWindow.bottom-rWindow.top;
::SetWindowPos(hWnd, NULL
, GetSystemMetrics(SM_CXSCREEN)/2-cx/2
, GetSystemMetrics(SM_CYSCREEN)/2-cy/2
, cx, cy
, 0
);
return 0L;
}
};
return DefWindowProc(hWnd, nMessage, wParam, lParam);
}
else
{
switch(nMessage){
case WM_DESTROY:
{
LRESULT returncode;
DestroyClientWindows(lpInfo);
returncode=DefWindowProc(hWnd, nMessage, wParam, lParam);
lpInfo->hWnd=NULL;
PostQuitMessage(0);
return returncode;
}
case WM_COMMAND:
switch(LOWORD(wParam)){
case ID_ADD:
if(HIWORD(wParam)==BN_CLICKED)
{
AddData(hWnd, lpInfo);
}
break;
case ID_COPY:
::SendMessage(lpInfo->hEdit, EM_SETSEL, 0L, -1);
::SendMessage(lpInfo->hEdit, WM_COPY, 0L, 0L);
break;
case ID_CLEAR:
if(HIWORD(wParam)==BN_CLICKED)
{
ClearData(lpInfo);
}
break;
};
return DefWindowProc(hWnd, nMessage, wParam, lParam);
case WM_SIZE:
switch(wParam){
case SIZE_MINIMIZED:
break;
default:
{
RECT rClient;
GetClientRect(hWnd, &rClient);
::SetWindowPos(lpInfo->hAdd, NULL
, 0, 0, 100, 32, 0);
::SetWindowPos(lpInfo->hCopy, NULL
, 100, 0, 100, 32, 0);
::SetWindowPos(lpInfo->hClear, NULL
, 200, 0, 100, 32, 0);
::SetWindowPos(lpInfo->hBig, NULL
, 300, 0, 100, 32, 0);
::SetWindowPos(lpInfo->hReg, NULL
, 400, 0, 100, 32, 0);
::SetWindowPos(lpInfo->hTry, NULL
, 500, 0, 100, 32, 0);
rClient.top+=32;
::SetWindowPos(lpInfo->hEdit, NULL
, rClient.left, rClient.top
, rClient.right-rClient.left
, rClient.bottom-rClient.top
, 0);
}
break;
};
return 0L;
};
return DefWindowProc(hWnd, nMessage, wParam, lParam);
}
}
BOOL RegisterWindowClass(HINSTANCE hInstance)
{
s_hInstanceHandle=hInstance;
// -------- ウィンドウクラスの登録 ---------
WNDCLASSEX wc; // ウィンドウクラス構造体
ZeroMemory(&wc, sizeof(wc));
wc.cbSize =sizeof(wc);
wc.cbClsExtra =0;
wc.cbWndExtra =sizeof(SIMPLEWINDOWINFO*); // 補足ウィンドウメモリ
wc.hInstance =hInstance;
wc.hIcon =NULL;
wc.hCursor =NULL;
wc.lpszMenuName =NULL; // メニューリソース名
wc.hIconSm =NULL;
// ------- 通常のウィンドウ(ネズミ色) -------
wc.style =CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName=s_lpWindowClassName;
wc.lpfnWndProc =LoterryWndProc;
wc.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);
if(!RegisterClassEx(&wc))
return FALSE;
return TRUE;
}
void UnregisterWindowClass()
{
UnregisterClass(s_lpWindowClassName, s_hInstanceHandle);
}
HRESULT MessageLoop(HINSTANCE hInstance)
{
SIMPLEWINDOWINFO s_SimpleWindow;
ZeroMemory(&s_SimpleWindow, sizeof(s_SimpleWindow));
AllocAllData(&s_SimpleWindow);
// ----- initialize
if(!RegisterWindowClass(hInstance))
{
FreeAllData(&s_SimpleWindow);
return 0;
}
if(::CreateWindowEx(0, s_lpWindowClassName, "Simple Window"
, WS_OVERLAPPEDWINDOW| WS_CLIPCHILDREN| WS_VISIBLE|WS_POPUP,
0, 0, 600, 400, NULL,
NULL, s_hInstanceHandle, &s_SimpleWindow)==NULL)
{
UnregisterWindowClass();
FreeAllData(&s_SimpleWindow);
return E_OUTOFMEMORY;
}
MSG msg;
while(::GetMessage(&msg, NULL,NULL,NULL))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
// ----- release
UnregisterWindowClass();
FreeAllData(&s_SimpleWindow);
return S_OK;
}
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCommandLine, int nCmdShow)
{
MessageLoop(hInstance);
return 0;
}