NoFoldEm program
This is the program:
less than question mark space php
//////////////////////////////////////////////////////
// //
// INTRODUCTION //
// //
//////////////////////////////////////////////////////
/*
This script implements the rules of Texas Hold 'em Poker
and calculates the winning percentages for each possible
starter hand. It also calculates how often each type of hand will
win (e.g., Full House) for each starter hand.
This script was developed by Tom Cool, web at tomcool dot us,
and is submitted to the public domain.
*/
//////////////////////////////////////////////////////
// //
// GLOBAL VARIABLES //
// //
//////////////////////////////////////////////////////
$num_shuffles = 1;
$num_seats = 10;
$num_deals = 250000;
$num_big_loops = 1000; // number of outer loops of the program, used to cache results during long, multi-hour runs
$num_nutz = $num_seats * $num_deals; // number of times the (hopefully) nuts are tossed down
$name_script = "Random_Practice_17_php";
$control_dir = "C://Random/";
$time_limit = (100 * 60 * 60); // the number of (hours * minutes * seconds) that this script will be allowed to run
$debugging_script = false;
$want_log_book = true;
$happy = true; // So says Dr. Pangloss
$glad = $happy; // So says ex-PFC Wintergreen
//////////////////////////////////////////////////////
// //
// END GLOBAL VARIABLES //
// //
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// //
// BEGIN PROGRAM //
// //
//////////////////////////////////////////////////////
set_time_limit($time_limit); // allows this script to run for (this many) seconds
$run_log = fopen($control_dir . "Run_Log.htm", "w"); // opens a run log, used for debugging
$start_time_in_seconds = array_sum(explode(' ', microtime())); // used to document execution time of script; see end of script
fwrite ($run_log, "This is an execution of the " . $name_script . " on " . date("F j, Y, H:i:s") . " \n");
$rank_straight_flush_string = "1,AKQJT;2,KQJT9;3,QJT98;4,JT987;5,T9876;6,98765;7,87654;8,76543;9,65432;10,5432A;";
$rank_straight_flush_lines = explode (";", $rank_straight_flush_string);
foreach ($rank_straight_flush_lines as $rank_straight_flush_line)
{
$ranks_straight_flush_ = explode (",", $rank_straight_flush_line);
if (strlen($ranks_straight_flush_[0]) > 0)
{
$ranks_straight_flush[$ranks_straight_flush_[1]]['rank'] = $ranks_straight_flush_[0];
fwrite ($run_log, "Straight flush ===" . $ranks_straight_flush_[1] . "===" . $ranks_straight_flush[$ranks_straight_flush_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_four_kind_string = "11,AAAA;12,KKKK;13,QQQQ;14,JJJJ;15,TTTT;16,9999;17,8888;18,7777;19,6666;20,5555;21,4444;" .
"22,3333;23,2222;";
$rank_four_kind_lines = explode (";", $rank_four_kind_string);
foreach ($rank_four_kind_lines as $rank_four_kind_line)
{
$ranks_four_kind_ = explode (",", $rank_four_kind_line);
if (strlen($ranks_four_kind_[0]) > 0)
{
$ranks_four_kind[$ranks_four_kind_[1]]['rank'] = $ranks_four_kind_[0];
fwrite ($run_log, "Four Kind ===" . $ranks_four_kind_[1] . "===" . $ranks_four_kind[$ranks_four_kind_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_full_house_string = "24,AAAKK;25,AAAQQ;26,AAAJJ;27,AAATT;28,AAA99;29,AAA88;30,AAA77;31,AAA66;32,AAA55;" .
"33,AAA44;34,AAA33;35,AAA22;36,KKKAA;37,KKKQQ;38,KKKJJ;39,KKKTT;40,KKK99;41,KKK88;42,KKK77;43,KKK66;44,KKK55;" .
"45,KKK44;46,KKK33;47,KKK22;48,QQQAA;49,QQQKK;50,QQQJJ;51,QQQTT;52,QQQ99;53,QQQ88;54,QQQ77;55,QQQ66;56,QQQ55;" .
"57,QQQ44;58,QQQ33;59,QQQ22;60,JJJAA;61,JJJKK;62,JJJQQ;63,JJJTT;64,JJJ99;65,JJJ88;66,JJJ77;67,JJJ66;68,JJJ55;" .
"69,JJJ44;70,JJJ33;71,JJJ22;72,TTTAA;73,TTTKK;74,TTTQQ;75,TTTJJ;76,TTT99;77,TTT88;78,TTT77;79,TTT66;80,TTT55;" .
"81,TTT44;82,TTT33;83,TTT22;84,999AA;85,999KK;86,999QQ;87,999JJ;88,999TT;89,99988;90,99977;91,99966;92,99955;" .
"93,99944;94,99933;95,99922;96,888AA;97,888KK;98,888QQ;99,888JJ;100,888TT;101,88899;102,88877;103,88866;" .
"104,88855;105,88844;106,88833;107,88822;108,777AA;109,777KK;110,777QQ;111,777JJ;112,777TT;113,77799;114,77788;" .
"115,77766;116,77755;117,77744;118,77733;119,77722;120,666AA;121,666KK;122,666QQ;123,666JJ;124,666TT;125,66699;" .
"126,66688;127,66677;128,66655;129,66644;130,66633;131,66622;132,555AA;133,555KK;134,555QQ;135,555JJ;136,555TT;" .
"137,55599;138,55588;139,55577;140,55566;141,55544;142,55533;143,55522;144,444AA;145,444KK;146,444QQ;147,444JJ;" .
"148,444TT;149,44499;150,44488;151,44477;152,44466;153,44455;154,44433;155,44422;156,333AA;157,333KK;158,333QQ;" .
"159,333JJ;160,333TT;161,33399;162,33388;163,33377;164,33366;165,33355;166,33344;167,33322;168,222AA;169,222KK;" .
"170,222QQ;171,222JJ;172,222TT;173,22299;174,22288;175,22277;176,22266;177,22255;178,22244;179,22233;";
$rank_full_house_lines = explode (";", $rank_full_house_string);
foreach ($rank_full_house_lines as $rank_full_house_line)
{
$ranks_full_house_ = explode (",", $rank_full_house_line);
if (strlen($ranks_full_house_[0]) > 0)
{
$ranks_full_house[$ranks_full_house_[1]]['rank'] = $ranks_full_house_[0];
fwrite ($run_log, "Full house ===" . $ranks_full_house_[1] . "===" . $ranks_full_house[$ranks_full_house_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_flush_string = "180,A;181,K;182,Q;183,J;184,T;185,9;186,8;187,7;188,6;";
$rank_flush_lines = explode (";", $rank_flush_string);
foreach ($rank_flush_lines as $rank_flush_line)
{
$ranks_flush_ = explode (",", $rank_flush_line);
if (strlen($ranks_flush_[0]) > 0)
{
$ranks_flush[$ranks_flush_[1]]['rank'] = $ranks_flush_[0];
fwrite ($run_log, "Flush ===" . $ranks_flush_[1] . "===" . $ranks_flush[$ranks_flush_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_straight_string = "189,AKQJT;190,KQJT9;191,QJT98;192,JT987;193,T9876;194,98765;195,87654;196,76543;" .
"197,65432;198,5432A;";
$rank_straight_lines = explode (";", $rank_straight_string);
foreach ($rank_straight_lines as $rank_straight_line)
{
$ranks_straight_ = explode (",", $rank_straight_line);
if (strlen($ranks_straight_[0]) > 0)
{
$ranks_straight[$ranks_straight_[1]]['rank'] = $ranks_straight_[0];
fwrite ($run_log, "straight ===" . $ranks_straight_[1] . "===" . $ranks_straight[$ranks_straight_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_three_kind_string = "199,AAA;200,KKK;201,QQQ;202,JJJ;203,TTT;204,999;205,888;206,777;207,666;208,555;" .
"209,444;210,333;211,222;";
$rank_three_kind_lines = explode (";", $rank_three_kind_string);
foreach ($rank_three_kind_lines as $rank_three_kind_line)
{
$ranks_three_kind_ = explode (",", $rank_three_kind_line);
if (strlen($ranks_three_kind_[0]) > 0)
{
$ranks_three_kind[$ranks_three_kind_[1]]['rank'] = $ranks_three_kind_[0];
fwrite ($run_log, "three_kind ===" . $ranks_three_kind_[1] . "===" . $ranks_three_kind[$ranks_three_kind_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_two_pairs_string = "212,AAKK;213,AAQQ;214,AAJJ;215,AATT;216,AA99;217,AA88;218,AA77;219,AA66;220,AA55;221,AA44;" .
"222,AA33;223,AA22;224,KKQQ;225,KKJJ;226,KKTT;227,KK99;228,KK88;229,KK77;230,KK66;231,KK55;232,KK44;233,KK33;" .
"234,KK22;235,QQJJ;236,QQTT;237,QQ99;238,QQ88;239,QQ77;240,QQ66;241,QQ55;242,QQ44;243,QQ33;244,QQ22;245,JJTT;" .
"246,JJ99;247,JJ88;248,JJ77;249,JJ66;250,JJ55;251,JJ44;252,JJ33;253,JJ22;254,TT99;255,TT88;256,TT77;257,TT66;" .
"258,TT55;259,TT44;260,TT33;261,TT22;262,9988;263,9977;264,9966;265,9955;266,9944;267,9933;268,9922;269,8877;" .
"270,8866;271,8855;272,8844;273,8833;274,8822;275,7766;276,7755;277,7744;278,7733;279,7722;280,6655;281,6644;" .
"282,6633;283,6622;284,5544;285,5533;286,5522;287,4433;288,4422;289,3322;";
$rank_two_pairs_lines = explode (";", $rank_two_pairs_string);
foreach ($rank_two_pairs_lines as $rank_two_pairs_line)
{
$ranks_two_pairs_ = explode (",", $rank_two_pairs_line);
if (strlen($ranks_two_pairs_[0]) > 0)
{
$ranks_two_pairs[$ranks_two_pairs_[1]]['rank'] = $ranks_two_pairs_[0];
fwrite ($run_log, "two_pairs ===" . $ranks_two_pairs_[1] . "===" . $ranks_two_pairs[$ranks_two_pairs_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_one_pair_string = "290,AA;291,KK;292,QQ;293,JJ;294,TT;295,99;296,88;297,77;298,66;299,55;300,44;301,33;302,22;";
$rank_one_pair_lines = explode (";", $rank_one_pair_string);
foreach ($rank_one_pair_lines as $rank_one_pair_line)
{
$ranks_one_pair_ = explode (",", $rank_one_pair_line);
if (strlen($ranks_one_pair_[0]) > 0)
{
$ranks_one_pair[$ranks_one_pair_[1]]['rank'] = $ranks_one_pair_[0];
fwrite ($run_log, "one_pair ===" . $ranks_one_pair_[1] . "===" . $ranks_one_pair[$ranks_one_pair_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_high_card_string = "303,A;304,K;305,Q;306,J;307,T;308,9;309,8;310,7;";
$rank_high_card_lines = explode (";", $rank_high_card_string);
foreach ($rank_high_card_lines as $rank_high_card_line)
{
$ranks_high_card_ = explode (",", $rank_high_card_line);
if (strlen($ranks_high_card_[0]) > 0)
{
$ranks_high_card[$ranks_high_card_[1]]['rank'] = $ranks_high_card_[0];
fwrite ($run_log, "high_card ===" . $ranks_high_card_[1] . "===" . $ranks_high_card[$ranks_high_card_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$rank_kicker_string = "14,A;13,K;12,Q;11,J;10,T;9,9;8,8;7,7;6,6;5,5;4,4;3,3;2,2;";
$rank_kicker_lines = explode (";", $rank_kicker_string);
foreach ($rank_kicker_lines as $rank_kicker_line)
{
$ranks_kicker_ = explode (",", $rank_kicker_line);
if (strlen($ranks_kicker_[0]) > 0)
{
$ranks_kicker[$ranks_kicker_[1]]['rank'] = $ranks_kicker_[0];
fwrite ($run_log, "kicker ===" . $ranks_kicker_[1] . "===" . $ranks_kicker[$ranks_kicker_[1]]['rank'] . "=== \n");
} // end if
} // end foreach
$hole_cards_string = "22;32;32s;33;42;42s;43;43s;44;52;52s;53;53s;54;54s;55;62;62s;63;63s;64;64s;65;65s;" .
"66;72;72s;73;73s;74;74s;75;75s;76;76s;77;82;82s;83;83s;84;84s;85;85s;86;86s;87;87s;88;92;92s;93;93s;94;94s;" .
"95;95s;96;96s;97;97s;98;98s;99;A2;A2s;A3;A3s;A4;A4s;A5;A5s;A6;A6s;A7;A7s;A8;A8s;A9;A9s;AA;AJ;AJs;AK;AKs;AQ;AQs;" .
"AT;ATs;J2;J2s;J3;J3s;J4;J4s;J5;J5s;J6;J6s;J7;J7s;J8;J8s;J9;J9s;JJ;JT;JTs;K2;K2s;K3;K3s;K4;K4s;K5;K5s;K6;K6s;" .
"K7;K7s;K8;K8s;K9;K9s;KJ;KJs;KK;KQ;KQs;KT;KTs;Q2;Q2s;Q3;Q3s;Q4;Q4s;Q5;Q5s;Q6;Q6s;Q7;Q7s;Q8;Q8s;Q9;Q9s;QJ;QJs;" .
"QQ;QT;QTs;T2;T2s;T3;T3s;T4;T4s;T5;T5s;T6;T6s;T7;T7s;T8;T8s;T9;T9s;TT;";
$card_order_string = "A;K;Q;J;T;9;8;7;6;5;4;3;2;";
$cards_ord = explode (";", $card_order_string);
// $hot_bits is a string of random hexadecimal numbers generated by radioactive decay.
// provided by
$hot_bits = "07C60C7D5BED7DB5FEFC3144176B5BA60BFE649E063753911EFE7663CCCC40F6D0A6BF4CDD65CA0F85E68F03BF3A939FAD27A0ABA8178BFFA2410644C3D23D568726E2E7062C36C9938469A481ADD22C0ACDDFAAF6A5FC5BAA73F61683646879F7C0BE771E102FB9CA7FB1FE28EEEF46A4961A3FF4D692D6AEF0F5EDE6648E9364A7BC38C28BADBAFD58F38208FAC20418B9A2C4E4AA58E5A887EAFF77A67B74E252F9D9A0225F9926DC202C151B8A2FF08BD9A2BC22FDA55E5764B1AFC745689650D94822AB84D3D5E7AB50C097D989C25468AC8EA750EE980DEDFE42DA8F1431EA4A720EDAAA2192591D9EE64D46A63F2889D1D55C94F6CE835A08D34151FF8350527E00AF4A984F60B13C0CE3EA76F1F5C2212C2A9249A23F04277E70CCBB5190F59618CB7B89723F51F68C3A14C364EA574A49FD241248FEAB7E52CA21C12BE04BF952DF383693DBDD5F9462E7C03BD89C358AAB51B4356159EECDFFCCE69458C246B79CA81A18322D2950DDC1F787CEC6E9535E026AEE719803BC4A4C3FA9F4EBC0448B44F096101740ADF3DDE75B855821B5D7D7D73A0B0BD01525EE6DA4047BCB581ACB5F01982CD6266B9B4A45C8B337735E1B66386BE93F7DCCC72A48997AF18CEDC563A0C2047BDBF92351BF40C88F538423AAE5AD3D866CF4CB40358484C3C23884C02C836587588C0DC222FE18D99D5F1E9136237D60D57A5B29CBF03CFBC5A923CC70C28A0B6DFA39C1BAC3CF3AA4F06753245C15B9BE479B6268828625DFF61C7B1111D05B2B9D0A3CD04A1CC034F73FCA11D838AA624C02BE02F1154DC78AC18C2EEB2FF66FBC8749E08610BCD0AA0C9CD2AD3963564884B0F7B56E9438ED0419C48345810263ACD11A430B06F13CB76B462BCD26458090232B5472E072940E7A9446DCF175454C6948EF1E67815767601A1795BF71DF3EAAAC68D1AB3912D49DC45976B76381DC95D8C8B5E2DBCB1A23E18F2045053EBC79922781FFCBFF59C8828F1340CA8F1FC0EFFFBCDED9062EBCA523CC71254EB091E2081F87BB3E634700C00B3CD206FC7DE5540DBC1409954F1DB4BA0F4FB97949FF9417CFAB62AB32662282ADD53A5B6AF28CA1310755053B6B53FFD070991E140840C2ED1DF55D21B37115CF072F2A3A51CDAA3A4E44F28BD4695BF50D19BD45BB83F610CAB2AAB74D6843D744EAFCB9C5E28A239D012A03AF270CBB57B5E61A4AD4001FF4249B2810B432898CFF1EB0A5E40A59AA1E796548889BACD88C0BE5A9B41942E6C3EFEDA0B492B3D574444991E2364281F25B88D68AC786AE94F8AECB5448A73B82774B0938D77E3E43F8E4E5DEA4862DB740677BDBAB1AD8FAD5EF615C63F7DEB5426C683052A630D90A58FE47AADF55A9D3FC9998D649077FE3DB5A343037EEDEB24C567D6DD09E9670019240ACE00BC82DA6A180DBDA628C539D3401261424103D68BEE946E83E06F44CA3D1CC76214A6889E10057DBED99D34A37C18865055FAE193EB0826657E84D0D93151207A5A7A5CDB0BDE6750D7CA254B49DBE188C44F00DE9E867C4A0CDF68C3E2EE2D9A11980CD3C38E3DD800DE3B0559AB51DEBB3CD8AC6011833C8D2F0217E301CF67FC73DB2D3CF0F77FDDC1E8E6EB0363886158CDB1EB5AE5B187BF792905794F2FE27EC28AE9D8B65E66FBA524ADB1FF72DBA932C3A4F31D73F1C7792D2882A9AA017497D099079E2A013ABF62096F17FE931CF07439374A19F57640B40408363E2D90ED949C3D91E0D4A537AB5E43C77B4225212D3E4A7ECA7EDBA1213CA442A00B2BB634F307C75CBAE52F96A63E38CA827D0BAE5A49A45C9C53CEC39466A81BE58EB356E7349829DD3A704E742B0D6C9B91FB333CA463DFD1C3486DDEC0DAFCB3FFB6A3802E854BC93A11982BAA3C9036C229550CC6E750AD7ED6051E5224138DB9F525673E7C38720B2D0052C3C465A2D6057C3ED7CBCB16A44066B6DFC6C77D644ACEF24039686F73782CAB4F54A49679ABA85D22AE5133F0919963BD4FBCAF85B97D6A88F7D92E3644867EA95766C0EAA8F579E51D0C30A989F5DACE2C121BE1DA97293765E263692EC2E5AF6746FEDEF3CE702C7D7B818B2E7077795185680D4B77FB322BF3D99ED1BD7DB2CB189E293F73E62710C3F0FA7948D86F5D1A1BE9DECBA09D642B57F5EB54B01FF537F98B2ACB7EDE9C2B2A5ED9DAD20848EDF61FFC058FAF7AF0A49CE692B425E0F80A2C6A2AA4BB6E0B10238CDC128750428746D2F1BC44601B6BA029F88851B17DA1EFEB21C1659443095FD3ACB94FF346E938993B711922C5E87A0D4D181D2098727A6DCEADD97E687470CD87C7B7C3C91B55235D6F9F01D5CCA6BEBFF6CD756A3E3F78EBAD6DBBB23276AFA250E9C02B76E2A150641FE3FA95C7C47B8736E97E19329BE600B3359A88A4D6599DC95F78D952515E143F352A154EF265738AFD745E54B7CD16F09B471B99746D0872BDA355991102DBE3D2F4798A87E58E2C120DDDB6EF5BF1A85BDCDC967BADE3DF02242735782AABA61058B1CA05627050CA1624E7F05234E686B67FA8D5A2029D2135364F8E0E706C7CAF09EFD93BC4637CDC15EE7D075D6F8EBA9E56F00E6023C5E1B7F78724E521829DF746EE9BB312B01BFA35F05A28475A8963C53668529BE0944272F82A32A902BF7EB1528F8F8448B815B151651CC4B3D7116A7767F0BA14DAC264B508CF5FD01CADC6FC5F526DEB3B3E67E68016AFF06A27F2252904A85817E94B9F70FB6F7C2E1116BA682F88F9E891D90C1DB0C5D7BC9421AC0CD0EC32FCA13EA76322605B464B4CB4477EEEE9DE6645032F46580D58C70577CD26CDE7336EEE27FD536A38D7FD3950768008C536837926D04F420FCFA0207872C975D0C998B1D79EA6691FB61BA69BA003F5A51D7703168FFCFE8AEBB1D874C61A27C1DEC74A28AA3896094E7F6800D30694838D02CB7D1EB158E442A08750AAB07815024330B146E7386612B06E29608E251056ED04CB9017DDA84F888492EC33ABD0E28BB1898296DA43F7CAF8678115F0DC54F810312B3CAF201AAF7898FA45161CCFDEADE5A4521FBB4FE3F194B6E317DADB03E1E77D8389F42916C63FEE7A96176B7C223350765C2862EE051070922326190F8CEEB803AEB49DAF4FDA0DE733847D423EB98859619E1DBFB7726D209872F39C85E788BD05E9FABFBC5A35851450517E8F7091D4148D1220C20DD81C55D3C8A84540C80E07F0057BF2441274BA45373630ECCDCB477A577566C2B3391F028AC7551DA58CD03A263DD8F9C50CF8253A79C3CD3515BE405F9B8F7B62FF39C50553CA58B340BA37471CC125E5E8460CCEE59509FC0DA781C71C0B1B59B554347C108BF8E28386F9DF4907629AFF134CAC8908958E93BF45199C2A049EAF701A352FD92F3A9DF21FF5EC308002CE2DC8799CB697C5E4139C4B7A0196BD527A1B12910FACD8B6F8AFE22286757EFE039289ACDE6602C87F5764956FAFC07D710BDD0ACA063F41A04EDF8E40E7DCB0CA05000810C89648948B30CF77C4F5357EF95CAE22A844C087D6B9F0E0A932C6B46C563A9DE02DE62876A5F7CAF0BC476EC69A72BC085E302E94462BF1B3B2FE32EF29B94FF086F66E8C4EF8EF5D055B4BD17D3A1B9512D41F9218D2D1D9F275752EF41CC5BE4881AD563545EBAA944EEE4384C45EA02C2D044CF1FD3DCBBC580C0AB368739AAC516BFDF38FE1A928685BA14B6B506D4922B7B2AA6780C32CAD32F2D3F89766B1E7BE724A034A60C6DBB4661BF0D470B045661C6F33E06D60DB741D66C02F16DF8D8B755ADBDFC61B205FFD66CB259CD2AD95DC36EF62437CC17C75F525E31CD57148448E46F3FF1EBF4121A9CF2EBB01A2645A11CC968035339C2B00DC88C942792614B2223FFC8DA11F76ED3C1F220813FD54BB80F157B5CFE0141B91C8B0F03721145F1689037245A32C1676487569A3D7B0780A1F7B5E8687224954DAB7891D05C15E57F58578077A60E96A82D6428DED78977A197B174AAA466E9828F33B81C632AB7192C36F44AD6A29310850FF455EA294A475C8E39586F012A6ECF6A4334BC51178129623736C5056A4819CC16DCFF65492CEB4E1F9FFAF4506700A6357643CB1175F46B8A138AA4431A7CFE1BD72006E6AF1E293FE01872FC64068D17D05ED9AB78404DE1F21D3363244435E908569218D7CB2B3CE05D16D7500A451CE849AF3F56F645E11BC556C0825511AB7AF623D83253A7CE1102428C02327AFEA7F8F9CBD2119B548C47C6E31537F92697451B45D54E27A5F36F113711FBC239D7D0808F8DAE9D6E043CA77E7FE14BA48D341A3C6513246904287890DD963883BE3B70F63A0029AD53766011421BC76CB4B9FBB6B92685330230DB5D6F5E6EABEAFB6A303CF2F467B41298809F7702002CA83FC770087187F8010C4DA17E7EA8DA79F2FD46A96B59F69F0FF8321B5D1DC463BFAF0FBB6FFFFD23206B380ACBCB1094C44D89FC6064C7E6611AB76652ECA34CF1D995F73BB17611C466ADB29F5C6D2384987EEA4468781A32BEE02B689DD0809105BC35375A68680F2DF2C0BEB753A9D9B142E7A2790B7D8699A2D242BD6A161261AB3C0EE1FD805CF1F772F72AD12ED3573D75D6CE2C8F695D5F58CF7D95A72B48A434A61AF72A4E5FC545248F9FF33602B32051524C3CF49D3C86564C399C3DFD3B109DFE6A0EF9C750EBFDAED963A591B6F86D696B64258DB9A1A7D9958DC8E5AEF7F5F3F2D0889A2050E12F3CF4B00539E74CB806540E5F75C403C04E75BB21E97F253F7B70559EB154537806515CD17F57ADFED939F7F1E759FFF72EEF1BAE18E926E2BA2EFC3EF483EF284F8EB429B8686E107D9D1E07DC49E7B1C46A1518EC6C3C14C00A39126078C799DAB4BC0D4E47068D59ED17A194F49F08B92D465FBE3B505CF947F606FBA09D60BFAFD2AE4A1144D8BB255B5FADBD92B73B7BAA82A4EF3296B1735F141D08D3BDD9C972F522C338F5ED84D1E56B0C4F58A1974D90D2C34AC4B3A1D4E7E9EC8DC6563913682115589FFF9D390D83467C5F7672B5EA26275F004FF399D2CD270EF38C17C3D43A04946C6FFAB0B17D160645025961E5C2D5CB36CEA07E222431CBB5653B5C1415CA3469E33755ACF89540144155EC59C12360C333A9523A76B6AE80FD81D952F8E535044E722D362678EF365158B731FEDF9D916BA0E3EC06730E9004FA36CD704C94AF23ABF33B0150B1BA631F81646BD32DD67C04F6D3A776C5F61FA35C10034306E052881D29AB258854A9889F81CDCD93D991F23001516DDD3A4AAE7A0218BE143BE21D7632F0CA4AE9A9A5DB9DEA977569403BE4C5B43AE33CAB57C5183C93A47C53A4E4ACE79E1F6271240629268E45B7E0438C9A7663DF3FF6DB8D6874994DA0BEA07FECCD741814D484E09C6D395E78F0BC4C5F7068E9EF380430FB5F042956FFBFB4665CA5144613D9B2CB0A79E52CFF685CD19F94E454F81681B711EC2D9D5FA0FCC6015603DB5BBB08DAC7890FDDB44C64A72E19AC260E7440096D9C786FF60ACC8F9800701394602F502FC12558E723559DBF4C72FB43EABA2EB881D252CB3E8C7729D7C79ADEFB00C5206FA969724476E88BF5F789BE901B2AA2E6CC9FF436938B55E02CF5B16064A6113940FA6F55A4B4D775CE2DEA14C54BDC481B43B6FEA879F7614D4961F9FD6A9250CCD3E2A3FFF50C900859A10943F94E94E89CA68C31E66C9E7FBAF9D3E55D959ACAEA4A5058F5754F32B6779979C893D62F168911EE1601A1AF7F97D8C1FD13FB21E950DFEF3BD75D10783F845E9F931D10017C63766C56A685D82C00A78D2A93BE729345B95B55AA4E4D5FCB04EB71D7FB966B370B9EB19840C9BBECBD14283E5684C4EEE27D398A7BC8191E9D935664F141AFB573303868C02FC10AA34D25E0AD4EC69628F244D6D21C02E34B9BC03282DC271E061D10C7FDA4AB29F17636405E66E29704CB89373C29F9DCA9678B22A1176EC0DD6905CBA3BFC81ECEED8D14974F5CE5053B739225BE0F5A70C26528975533B77791EC916E9B3C0847F26F7F118853D283883CAD6461CDEA20B3FCE35E24D24AC4B22245AE0169D3DC7BC33511D97C77BE4107972E78D13073824FE5022FBC24449EF4797465B5446DB00956B39FFAD7C52A1E4BF468CAF6D058136161286CB711E2FE4B74C53D3EDBA54B87390E34431ED9F2EFAF5DB8D82C7E84D552E342BEE7A5ADEFC76B854C5B2C7033E7BC5F6BEE0BD30663CBBB83C6EBC3BCF41030DC43452B5372D55C68E9498A275500DC7ED1FDFC3E7F264E00C6E7BC8BB353C14DAC9C5C9FAAD81001CBB67A224AB27F5037565DA86B908A84C2BA6B628459DDDD056980082CBFDFD4F13118F0446696233630ACEC5CF0507D2022B8AA19EC12B039A9E55F19B33A91F702C02E9B0DBDEAFF4E271E6D51BDE9285D50176EEB7F75B64E876147D7E5BDF89F43B38045AD80C6E23FECD98BCE7BAE2B742A511A6EE476BB6B5623F0F6BFE1F7A46A2C1DEF907A47CCDC7FE2A9E7AB1460B51B308EE0FE8215A7183F45C4C3DC31204A5739C16C3D6700CF1032A39C985E5D747D903FC520EA73B38B1BBF9A4622FCC702D217E120D718661A49B7252942EC095C43F129BDB87512FAB322681C1353E9F6727F91DC24215EFA3262309F82FAD54B029F5B743B242A54F3F6237EDED02170CFBC429C567D961CFEFD65772E614BC7677BE5648BF1F5542330024F00E1B7D484805E47FAA0C90B5E77F1573639CF92E6872F03F249C69BACB0F9095341B59A4C4D6CA45442CE20F27644C5D49CC47C258CA9CDFB282D07F868589FC7B7E9AC42A75B27D13EA494ED8BDEC834C5F218DF4FED8631BA43206D3F5D1070F2912646F427B1BE502E97A1C013EAE9A29DC9284CC2BE24E14E171BFF3C1E8FDE8B422529994D654DC10F56A171C77E7FE582504969A20F1C49B0E759B842C4AB4C469FF2DEE702D0BAAF519550578C46750A89FA5F69331847C6D22BDF9071ED5B0F55BAC9689294F69702ADFDC3C295E324F51AB02790B49AEB0F032D63F716FA6B05195420FCE14073A4566A5FFE89E16271D2F4CC1CAE70A7E945CAB8F7F98021620147FACCA568B67B283B74E3C8A09D2CB8A179F164E2490D7E7E3ADE368F81260DEF746E849DCB32D78733304589B6B9C97B3AE74A722413113B6987A2ADCDE45CD6AA0E3EEA945106BAFD2487E47118DA0F64862EB07CE657CFF2F603D43B1567EF095C99E02EFEA9D05850D7CFCFE3D433D2A1B4AEC2C7E852CD483DD12840447505CD2D25053465B56FF6F31528B095D7D34BB4DBF911AB3C3FD7820C8D5C03D13BCDD9903E56D5AC2080F90BDC4A0C66FE12079F5B3811ED1F5BA697709003A51B5CF1366764C28B1FAAD0F18A5AC440198D2C7EBD72AF94412A8BDF81A0DB8B0095B140A59FE1B1597992D18E8BEBC831949976776684CE06782E1561072D3588130A50A0FA1B8193265BAB233ECA2A1219E71E96CB145DA216D078614EFC9ABF242212A986B0B7F78902416420630A3E82A9184BB100410AA0D1DCCFC62EC71AD737647123F991A6CFB5D10DAFCA58E77360B12AFBC4BE94C2074195593C564E9E36529A76E299C8831894A1F7B5F499F3E838F03116760823C656894B06844426A254DEE4AAECC1C65165ECC45355F44F985FAD5450B413710CF02821F53491E078790359A569F5CF9FC64903021A4C00AE923C15B4B4127B1463A320409FF7445673FAD1FD45A349F9FC6E8EBADB57B47C86F5636DC3D20A5E16D019D54EA1C4039E27A0E5F0AF691DB9BE3914A364748DACDD3ABE6563464AA54ED0B503368F5B317F33B3EFB26D7D30745CD42AED339B78655D534ECEC6C435BA3F649A225FB2902A4AF8EC40672EC97B7C418E03EF84D90B4D406B6CE72C53321BB1A71027FB6CAB23E39A693C4E1317E777305B25E62AF14C8D3C085B5449D7E46D17AD5BA9C46ED796A0E1BC2CECFC1FF9FDCFE5D18ABD6E5F60B31D47182A1621E94ECE8A241E555FDFEF8EAF89A9E0C73996D5BD15502FF8E1F7A997EC437729D9A6BE16B9095F338D59442D40794E1A0A01E2BA51C09C1B96AFE7B9A855934433C6C9C204409E5A5ACB83823AC0822FA8B5F4E18773DF750E16956798340EF51F585B59C44E45CB18C77D5EDBD9CE663CF69E57A46A468FC8BCFCA9F7EBE37120D9D9D37BC478C875BD1685558C808DAEE65D127691DEE01EDAFAB1148E7F96A3353677545901C99AA4A8034A6BA91867E31D60114A3162961369F4F3AC5D3907304C838A72E01AD1A510B94236CB024CEF272756ABF2D7810F49DB3FBAAC7C501DB8C4E1535E6B4F58E89A23C791D843D1AE71F8AC15284C4F1E88D5F53FA8EF8E512B7DFD08E8B4AF029EA01DFE5581410DAC9D4F2D0AA4E95C3D040D4E41B451D5A8B47D1615054A756803FC05FAD8644D6A6A7940746532C1A4D88BB467F41FEF9C1ACE85554297A0D84517AC873907527E35562B122183BEBE3E731D4E201BCF7CCDBBF373AC793541CCD9B54F9BE1DF6FCF7D9D02EBD27E4D4DBAF63EF022189F32B29105D6B0DC78FA84CA11B1CC1704D07C6E07E6DE391B8DA205BDB5EABCB9C753BE2D699048133C4B85E7171D78982E374A8F43F2B948E57BE008CE70F8CCCD933E788BC60F03F723EFC5E7A5B5F6EB50A813EE10DFAD0D13B80438DCE02A38C33AB4750457241DD5CEB872818700BEEA724AFF1BECAD45875045261CE7FD08F8313AB7885DCF8AEDC5472A3C6FD46FCE708C013053D551A1CEAC3056E1773DE6AD166F104032C7CF82826C14B0378D449B746C5D1DBE25B7F06642DB35483C92DC5D0EF4C62824A8AC66C16A2226D685BBF82580C39B201EFA7033AF2C45FDC6BA90C68C735176http://www.fourmilab.ch/hotbits/HotBits:Genuine random numbers, generated by radioactie decay This site is deeloped and maintained by John Walker, founder of Autodesk, Inc. and co-author of AutoCAD. 39A3A788AFEF300A166B897470D501DB27D7833D56F8D0DF1EC0F80BF144C49D3AAB12348C22FC2FA5E4EB20A7CC3752550047E3329B4C552B653F94FACC7AE56DC1D0859F802E83DDEC93D079AA87026EA377EA55C41A9F1A3DAC71489F73393CB8C5552A2856D005BE3A85FCEE7BBE51437CAFDF88AB39EB34E4D084A0348B1EC67667C7399E80403DD6CAAC97821E959B955DC31AAC519DAE21EEFAB14632AF677BA23043B6BB559BF749945FAF99A371446DB5B1197FD6680D5963927BA3406352AB3AB095F56A389A59A648E613B3772E72593A0173ED4F40B904C9F8C4FF65A8D1043799AAB66023D5EFE355D625CBDCE7BD06812828E1EBBC3424F84190F5C162E49E2BCC1816DBC0606747BA95892A4B24B7D905744E46205EEC554435F761A7FE1C9CCB9050AFC797B1A16703D44521BFD6307FBFE81DA29C25DE3719343ABCD39772F6C340B957CA843B5513211526329AF97CA9AB06DC90DE58ED0EE2B14AC378606BCDCE698EC8CA46D04C0C7A54AD4E843F9226C6A0A91B70FE48EBE14FA1CEEF6ACE2840CBCD87ED49EA655718A9977E1DB909042A2C4F96D57661EEEC0D986716C58CB49295192436FE98A8D42CF6B5282D52DCD758AAE0DE7032AB3BA6204F61D870855AB1675D7150C889E97999C26917BC446CFF3E6F87E33A6250CCC0F924AD79F3977BA89DDBA1EF0705993AA356F19CC55BF5D0C97C04FE3D4893996BF1537027F8F5030B4DA5CDF1A2FBD8B5DF4EC73B7EEAF25EE8008184F64516ADE2DF0F0AB3F1085DB302F09C6462CE6618FACE1A3CB0CAB1116B53414379EF2B87CA114E19229F9F0B928CC255105D5A36E2C9FE55D7537B8A09CFEC4C164573FF0258B052A7A64BEFD8A955612FEC3CBDDB072EEAAC5CA4437EB0FAAE94F8BDD3C32F38FC5D401CB8BBC02F621AE778C38E4771EBFCFBE85D4235C2BBC1D6770427E7F4F10E9666909674A07749B9D381E54569E77C86E935DA40677D4E47753C73A81743449F533AEF33F2F6CA5CD914D451903C1DD9B4E64B260AF46DC318B4F77FF7EC306AE79B01C0E2F150B8EA9BE341CCE856310580EE348E75658BBA7953C63C1985AF0465435360C7B69FBEB31FAE6FBF3F3F912145DB883DB445224229BA8C69E7AAA1F73C24FAE103BCF7BE8087C9BF7D8CE73F01536FAF9A49DBF162C366463F0FE8F1CD8EC44A89955D39229D1A92D693960AFCCE0684FAF8A47789434E58D5CE5A3580C2CFE8A238860C0EB478DB16DC32627AD6153904905E2A16B3D9AC164280F89798A907B6387928877D02292B745156C8531B7D6C0F87BECD7703368A48A4AAC135DBFC6DD701C7AB65C5AFF590F6F6104505D5BB44839A91047ABBF4373E714B93F51EAD6918A3622BE2228E72E1A782DEB7F6E794750B97D2BA3D6ABC75C4DDDA5A437A6E31945D5EB653DBFF5E60BCC9A905847189059E08EDA4163B714D48557ED1C6F6983B393B75DECEF0FDD5266C3B179D2EE908CFD17095F1C6A3373827999B66A77302B643EF4ACC1476745654A432F7661E96920E95B700E814EE45B2762E0E08C565C8D6F77ACC8AD19F55E204C8E271F98D12842C62701806555E3C7AEEA1D3CC70D05F3F776E283D3A3D21A222F43765B141B2C5F04A61D034D70BB0C02F689CBD4F4D534A6162797B1B157F33252FAE8F7914BE9117814EF08D89BFDD10856AEFF3AB9172CE86524CD4FFE2201EFB3EE3CEDC2DD95641B8AF42321F7C1BA89996B6E7B0F0E67BCCE3F31C172C320B474D11558F89BE094E133181A7A17D7E2B9AA8EBF6AA79F1A4E58F551FEAD67B7C0FD67C28B6B89A706399F2D10ABDB040F7154531D79B37AE97ABB27333A707BE193F4E837EA955D8FE11A25B0207DD9EE537EF100202B24F9A1972DE2DE929A6D6B21C8EBB2029E0185863EC2D58277B7B7A72AAC24731B9F3488960D0049F858499F75C13EC1D15C80B9616EF5A1C8B855476B6CE000FAAAB8BC2064F0FA82AB4DE56FAB894D00C357FF25907A8ED26DAA7949CB2FACE1DD7AE7E387F9306C581CAE4BD230F6C215AD04B54D52819662B94EDAE98339712AF502571E9CCD85C150CB6648D4AF7A1F9CCB3097DBECA25232259B3389E17EB3EF5FB53B69B4225DA0559ADEB1A72305D0EC85EC47B2F54CDF0880C8DED813C8F548428148BF59F94FE9E691E3CC52561F2D24FC4A8AD501B5380078A7F21C4B4990F8DEAD6D59EE6CE57EFCA03B68817066D2523DF6A974CCDDD9844D18E313E996181ED337C4671E9F0FF0D65CA749097F744957E970BED905A4568BAF70E6068B020D41D66764DA304341BCBF86DECC61EBC0AC2BA1FE2E8AA07868B65CC11E3E76665FD06AA25639F6D83AA7A544CAFBD7BA3EB56E68ADBCC9210049FBCDDCC35A50755AC53CB558D339EB8F33A205896A4DA4F619840F147C40A568EC311ED5CB3907BD078FE02FB02E8A2540E781FFACA2C9223A8A40F9864CB161F7ADFF24AA135C89E74C74ECDBDDF6E4414CF61FD8FC8976FBC61EB36C4B57AA56B9E50EB38EF1E28A0FDF0E6135A217DAB3A9A28ABED5FEFD224DF77A85EC0E24F1A3DFDCAD675F54E6ED3269D44F1D3624AEFFE170F1E8481AD67C8A85EC6D5D236E67DC4A3C1DEB799DC136F2D20E9733C1E2341C9BFF46807DC6E6353BE4749D6F0A9B01C8E001564A40B70F61539FE3654BE87221352656B498E6DAC1DFE15AB72CF89A7677B9F239944F8E5BBBDFFB382AA87C41E47E5B48CEEC05E25A263DACEEBCF3F7039F16D2F83138894172B6BEB3F2CDEEA1CF42FE102D05A91B2DC485CC878885CB9A996D55726C34271D55AFB36F917174D13F168261F73C059FDC81C3157F21D888F7D6392B6218275C460897C602FF7697745C13FCF1EE04938F436188070288DAB6AC308494AB07EBF03793ED4A6EB6B13A0E0E9B48D0DA209CB6BC5B7A1FC209DD7416107673953DEB90EC62129F0FC086749E1C60FB4FF959D4FD9A123CF1F36E272B0D701C8A337C500A88D53193FC4BA2D951E628F86BCB7FBBD02C329BE896FB2DBFFA84D9AE8E3AE9D16D6050E3E61A7192A516B67B6A8A19545DFE4FA17C9C44D388557587F0B24C2B8C97ED887B529D3DA5DF6A2B96BB5B61E23AD2749E0F1FB4FAA2E567ABFA3D38BBE7E59DA0D19874D39F866B1FB1B8A4702B7F1FCE09DD428786BDBA6A101AF0CC7F0A96561FD8C0A8A8FB87CE4DF3C74BF5B3E381744547EE45D35229516D7F1F4A64666844EFFBBF3D12DF93200E863310BBE40310CC7A0086CFA6DEF3337AA8927E1D2E90FB6712E98F7919E6BBD7BFF3AC987D2172FCCFDCE2AAA8F5D501A5792BB2327C38373A0A90C3E95527CB1169D05AC496EF3355F1511E69CEDAC8ACEBFEDFD08ED12C81F3487AB464B23715D443AC0A7146880747721C58AD3A583F275D376BD239882485D9694A2AAE3C8AA1D0F567C30FD058CBE3CCAAD022CB725E4AFCF5B19ECF75A2DEB2087E982BFBFC6FDDD99AD35C3C26B7499DB4004CC0868B152C039A9986CA9FBC2D606CA32045DAF9611C6CFBC93A994E1BB5189663FB69F91D72A1187A6C3C6DFC6D64F799875C9E3DFE3D031E6203DE02348EF2DA950FC2F1FD2B6B9755BF6E405FD0C132AB3A6C83E6871748A6161883580F42505B28D74E17320DFC48D8F0F5DC57D6B6998B8C2B70DEEE879E8E3A6B4BDC6FFFE937FE4FA045C65A9E05FFBE93B94CD21DEA2BA384014AB11C70F3CED9425316597676A65A7D944F1AD8DADF5596CA96090E7A8F1AAB0EF257D42A978B49E3BE990F6808EAFEF464126B2C3CAA198162209C26219FFA76A28331D02B4C763DBDBAC62F55A9ECBA8CCFC093D3D8F6C3D24FE0FE1311EB65BC03245A1F103B2898ADF494DD6BEA6F5AA03C5DD29B53BE0FABCED3345DFE0D067FB3D6D0C1E3E7A51AF9A763DD422F9CBA820F8C98B6A2DB0BEF3CC8FB1726F6472FB639F8323DFF95BB1FCA5CD1408309A640BE1F8A0E21A17ABD3A54C6F659677E1D2F2986CE84462B8E0664A7206E56250C1C3B79F12ACB5C730BBE760C7AA1235C8281C3B447E9A97AAC2D80DAAEA5BC9AAE15651B431E4759E74833094404BA2320FF8CF12D81194611C86445D263AB8F88DB0E4FC454E10E96E40AF4E5FB6E24DDA3BB2CCA252C4189DB6236BD5B907D4C1381FFA924ECB055025349D1EA1D54FB738A6DCC7BC894077310241F0EAE4DFE17919B4C88327FAB576F17911E6F68178AF30FB6290D1BF94D0938FB2A83DBB98D4F7CC94B7742E6B5661EB29D92C1EB78FEBCF1E71B99D80C5472D220D38DC7595F5A83916462A2D98832FFBD85A8859605D392404EE426D4B390E099CFA9E36F5CF301D185F45C1829D8B6BF9844D0D87D943D968F57BCD50CD2D9B00EC5D7B4870CBADA422090249299F738449B129D6FF3E96251B96B962167AF8A7C86E4284702F487314514C5223F3C23D5892EA5DE7AAC17CFCFD4B05706C6B511A6EB57625D88BA34FFBD7E50E51EA7A0CCB0543DFF57CE87768E5FFE60A46A8E4F21C07567BFD6E34EE905328A1F4D60D01DA598F68E6418C552BB67F9E047A56D7479B2B336AC88595E8FDEBD818DC5FBF10E7096AD63B9B7540E48349CE0CEC0CFBDCBC3FB531586D563439B62133FABFA0441A873D315A04724BFCE0FB8AC05BFE07FFC2F9E956EA02B62EF12237AB636BB17800275F41474FA79751D5C1E63FD61268DC1967BBA777DD599A3382C9E4484037DE74C9BA47DBCCDFB57C3908A5ED727A7080FB7187B273DEF91BAD7DF5465E8DDCA7C4B4804852168386ED80799AF7C9DCB7C991A2A1394E2660050771663C89FAA2E4B0466EFE3C7452873113127E77044A3301C0E5A7B87292658067E2183530FA0CCBB9AD40DDC2DCD00D42D7F12C1EEA4103794F6DB875BDF7807DB4CDC7C9D8D54CA60D563F1969C5AFE84BAAE22725CF7A5E7C87B84E505272B28929E148A038722C0AF8D5EAED627B33716FC014E1194BED4A9CF23EDC753D36609E948C0C2B3FE020742E2A0EE07A870C85EC20A93105C517C3ACC8809F1ADEAFD3F0F4E64F3FE401BB637C6D3BD0B94BF900B9BCA0AAB5EDFDF2E53C08930F0B110728C9798B37741FB121CB3AA6543FF6EDA83CBE4BABBB3BF2F0DBCAC9FCF2ED6CA4F6C2B54C28C09E9FC5466B0F9A4E2E30D3A048AEF8C8735921BBCA99B5287705F05E0544AF75463C916886A420B6AD4D50125693C1255FA04234E1C7F640D1C6A5EDB4535FBA591A74DBF130C21128213C758BAB3FD762B356CA71C97DCBFDD0359DFABA92F563B018D58841D78CC486F6167302990B021178D0A9FB69387B2B051A00D01C0B68AD10CADD92D87BC9A3C7DCC9234C0245F8E1A272D76DF0849BC02DB108BE180F179FEAC430938847FC8B341D2C9306A4CEE0076DEA537F7CD9AE91852881F9459D043E7DF71A151B1705E48B5FA8DEE86B1887BF8681B87731943BAE95E21EDA94A281697E4154D29431D93B125734FF00FA89400C72F81A2F9E013645C6E706717C332450FADA3CAEA7AC8358D6377A634022858CED89046FCA3C171797224FE312AEEAD9491181B5B27EA321E916836FB6F5BD89A376E308B079DB5A0FAFA5386DF7C50475752588FD747A1B04870D451BA48E78A62B873C2F87C24B00C8B9491DC424CCD9F2E8F815E4EF94C8B4B11C7FFF212CEF1F237A210046C14E5CE6F7749A086DA90E9F29F8ECF2C236D2C853CC8154C1B3234E494A7FA5990AE28E0B5198D2BBC04C14126C1C4F61320FEF10828539B8C36BAED36C27A3F886FB9D236B7A0546E15B6B035B8600070025C8B2A99FB510322FF07BE26B96992AEEFC3DF760E3A05126DABBEC9E4FD32F010B59428C0540972EB97258931CE4EB48F28886F25C6583460D1F23EA2D24CDF957BC21595B5D206B0C78D8628C609C195809B314091E21EB35377D8A151D306E192D60ED53B5218986C047EE9826919E17BC5EECF9CF550DEA45F33A69B91BF7E732B54CE4ED007E206FE306EBB32B6C642B0E4068E766CB7B357ED319D76C9071F133820FB79956B40C5CE679CBD6171008BDC120FF621E86BD8ACD71FB33DDB714EB47F89BC96F17A79D58919B41FFC3837D6D384472D79BEA8A2B7C693BB91EDE77A2514AF44443740A544239F7C3DBE5D42026DD8F729B1B12D8497E894526490A4A7110A66E62BDF4999F103FF77709B8A2153F7FC4FA46B837B92731ADD0EFEC8A22D417AECCD230F412EC50FA3B4D3842C197D374394D4E2C1937F5C3BDF7868265D6A3062FC7F4A8F63DA81D6BB6A0B4FF759F54BD5A5345A2A850025FD0EE8B108F0A0560CF20876D094EF68DDD8EFD8AEB32DD8CF45479C07E3ECEF9FC9905F021D733B2BADEB184E775DB75BE8F3B16376C7184AE80A7E3F413CD01E0531B66A7A44C438EF429B7D532CD2BD510770CBFFC4BC8928F41BF26D62FE8B01548212959024210C4AEB1687A370FE40750703331EEC228EC919FF9108BFC979B7F213A90DE8CC64EBA68F2AD3CBA617C471DF2FA8917B28802EBA8D679AB85F1A48690DC88E24269B3E3F71E00310E313FE1145FB5697A8C968E6559F8F9A20AE4A9FBD3DBC8ADD400C6A5A66E86CCFFF50A84658497988175E5E6B1439AD90CAA26A78D581DED081C99441527CD8490AC35E56CCC92739C8AB6FE535329D813BB51B7DB0FC1C230AA9F2089F5ADB0B534D54DF416E7E5E4EE1A318E4A5FF5548FE125F021C1C5A95313F3BE12D434415E3C523B769C72F0EAE87A83CB717B920C51590E97028179C91C526BEE16A56CB15D5E85BC1E4C1840822158EE0AAD7F42DCD81037B202C880068C532509342C135DA76044468A3AA53F754039EACA6B08A4B6063D667FC1432EB2680D1A18F61CDEB9EAF1CE0B29EB0476BBCB97D012CBBF11FA767526C401F307988C74B76220D32AC46BBF81F512D7385D2B8FC9E452CED0A34D2A205F5EBE9B00F1CC3FD0351E5B91F81BC02DEF88A12BF1B26254945C5285FB4C10D7A1E4665BA1D97BACF2BEF31C00A9F8E635E96300AB3987B91AA9E698663FA1C8624DF34898B4F35477CF09C01372F6DE824B2C4B3D61FC35D7BABCA0A2AC897FDFB248C39B53440FF26521886C4A14D3B0FFE98A0C2F62ED9129EF7CBADBE5AA74207F39535CAB6372962A2FB002BC62D1494D5C765B6644FCDCD07E1A51A097390306670A95F3F817A8F0680EC87D01CF3946B2593898C516349B82D14C0F0A639CC7917D94B7A13D65BBA9368CDFD92E4827FDFF1889D9097C0B218BE35B7CACFE9331018E26058661B8F9507718D0E82EA66AB9F2A6EE2A7AB86CC76F7C77ED0F215C79D7E22AD2A8FF5B588A00F129F2764C9D0F5A60F5BBD68135AD18F1E4E2B67D5FA26AEFC38CE902E4F71BC580410F517ABB473962759FC0A46970EDCDAAA203C54A4B847EC5048E78006C7B9E0DDB93500CE166019C641A62E7125B3E841094872F6C7AFDA5166258D6FDFF88D4085B73FED0E5944B1081803998B38F001E0BD7D098735C6FF0024BF6350BE2EB6095312226D85FAE697D79F5926F5E16BE468862497CADD1F0890112B7EDDB56E879C5215157D4DF808B98E2059B54F49FBF29F6E58FACFD8877AAB088622D9666EC8D77BDF7368E93C479A4881C1BA863F63511FFCD0CDF64656E044E340F836EFEBCCFF813CC33233FF43C63F9A505D00ABEC34B86745D14D603AE1D5FDCCBB6476A22FA97D99D8391984BCA30033817DA0B14017CB6772D4C255990436467BB93AC7F2BDE26661D35DE9D482A3CF4C0FEB236AEA69DA7E091BDC87ECA1B48B09FDBAB2D970E533CDF7853290D27BD64FECCA006BBF2F0EE15C2335B11D9AAA883913E0BDB2A441BF604C298D316417275A30BE7ACBD78AF94EC55DF917DBE2F7B77756BFAF28AB34DBBDE75DA0437C6E54CB081C7882504E0865222F9C8E081F9CF97093D34C74E11BDC1A2AA95BB2BE947559253D0610DDE920DF2D49C8183FA3D6273066AFFFA0FA6DFFB2022A6B796EC75733239006FB87B51FA14A8402C662E2ACFE308EA5023FAD376D6CD10F7D6D9AD9696E92FE0F5B4FF1E306DE5A2C3C58A15B21F4FEC33ECB66F3BF746B169A9C99482B07B551695AAE3970039733F016530B6072F32D622ECA0D04B00A7FEBB6EBDF57C87F9DE2FE66FEB0587B9509C6DE8CA4890C67721AF85CE897A5345C23F0B6A3B3F6DC17BB7F64D98A9D6F61CABBC7ACB6E9956E3A4CF4054AE1BA4AA21CC8139D2CCDB5D61C7AC37725D8853F95F47DD852DF4FC4879F7EB4D3836C71906104D61442F77AF251A752494569A80159720B4D34E713EAE6689A59DA10369D78651A6252ACB3DDCB76CF68492EDEC806397245EB014280F5487BF6084849948B68260291547D6072FDFE3D4FD6CA527E8B63A6BF84726DE69EA6B43C95A37EC04D1FE43027C80901A544089DE944173C6A07ACDC1C47DE10FDB01DFBDF6A00F1D557EF425727313E1D7B4B43AD71FA767B35B01EE88C866F32F301AFCD1A59DAF987664C24B1CDD8471768F511C2A51BE13FE0DDD9FFF2CB69425EBC30E95BC51130E25F02BBEA2433E41D6F999B19F323514ACEE3F57C05F795640D7A720A5F037D740F321E0793958DB9AA3A9E9B8E144A2A7DCAB1BFC6FEE19593CEDC881E21A1BF9D26EEC00EA69AA8528C5AC2565996462E74C0F66C5452F88AA745D024141B81767E0EE1832EC257AE98D5FE47B09B242C8E5B5EA0B064809F838823B214244592345FEC6CDED753532C40B905D369403B1AC1BA626E9485A5AFAF8ABD157619BC4CF638BC00B1082D7A58BF0580A44779A7ABA2753F4F89B7BAFB0539A084CB18727E9D7D1CB6AA022F35BB56F2324897E396358E69E4A6CAB7290D5A47FFD88C34F041BFB2E3344AA888965F11BD08723C9CD5BD089CF036213D8060B66491A5643D686B13959870470A348689DA5D5941482658151AAE93598441442EC0B7C32ABC1DA1B1C9752611F8A5EA46504A1BEA4CBCDE0EE7B5FBDF786DBE6B91BE90A8CAB0DDDE56B3D88F5C15EBDB33207B4630A3B319CD2628810CBDE1B5A3E7A153C1DAB195792C68E65B91355B438192F1F42D90D56AB9BDB85501EBB09F7E3D312F5A6390CB070867967B547B496253D554F13584FEBC762370EE6C8D5C33EE9D9B4776E0C7B36C36690FED23B2C3CD3D6FB8364FE0324DFEE1F2C4BC431D394EE4309EF67EA2DB9DF22816EB8E1735079F8EEA398B777494209424E0A44C27EA1204EC733005D1D15F90EE10A2792F82F4B22704F37398E711EDD0B135B9B2D23DA87B2FED61288C0F0B5F3160EBE30854FE4256A7F289809A88ED5CB4E4D462D9CF7A9FA8089481BC8CDBD5E6485F80113D410E851FBCAD6E09D3AB657C2E7EB7D469BE82F20A7DE9B81DF92630D6516FEC668FCE868276261CCEFC10E53C35870C4E12E5FEF52489BE266BC447CFBD9494215E3285AAC28200092297E6B7BE54182785E3029468F370EDC8675B5270E363607E54FF9F743B4339A384A1609C4BBE60A3940707FC7CD3C69CFC976E0BEB4F51BA04C7388945CDD524170C7C328DF6470A306893EA426BB78644F5C6536582627E6AD00C4345CD4DD5F86DE9E4B7B0220E71401121297BF2CA7D03051E2B24D8E7C01F73B0FB1EDBA5AE5C7EBFBBAAB2F6C9C9CA11291B6316E7EA4B3751F2F703FADBA3CBC23E5520A50EAC6731C202D3CC84678675A1F7955487D20CCA3771D56D74C110156B12A88B83A7FFCC0FBC77C077AB951AAFE4C925D3D4B060240015A608D3EEE7CAF28B02AB5A17B3E7C4E4158DAF2CCAE4DF1F71575C4E141742BA9F48EEA280847A62A2CFA613E3CE601F7BE6E983E08B5774ECC6E131638063C72479E400856AFE5D742D713B072EC5D6238E8F398C1CA6B836CE7B82D122C32038B4598CE64C9E2F9263E69137213C7BE0A3D470436F603D0FC8665B61E95C8F931991D9F5C10FBB46094B8BC5FFA3A0408FC1A01176CF5265AF8F49B5D2C9ED23F3DF201BBB661CB8075A572422214B82545F639EC29BB4CA98D966DF402908DF26D4FC2C92EAF452BFDDA87D11DCE3922730EFA0D563ABD026D7D5F5407F7384703EA0BE769218C9E94817FC7E405E20ECD946ECE441CC9EA82544210034B30A6CCE73844E30BFE5699A656DD2A1A0F581FB503089887D618B895B53AB0EBF5D43B2C8EFF4C3DADB6F5C0232D8977F096442E43D105EBDE9ADFAD9D9F58BCEC4F4DEF18367B8380C4B391645F84B24BE2965FAB2C02721ED393FA94BF2373437B8F6B538B0F48634FBD7CDDD489D7D40FD34CE8CF6D351621A438F0FF38929EBABC7EDD998279757EB59F7091F5C1CB9ABB33F1698135215E80BDD8F1E6AABA2668A00BA3683D2960C50119A91DE8B5DA4B9B520A5F5A0E3BA2CA19852D8F221AB74B70B0E8348C9C8EB207708BBF5D0A697D7B986CF0AD39509D8DE8C884FA0B0764EB4565C9E2C25D77561F3ACF6D19D95CA4D587091BF960829158D963111F89C8BC7CE519C0A1827516251DEE4AE739105E88FAC7BD027E64081BC5D173610AB83DECBCC77B359DBE11F52BDCD70448C5BC98524191EEBF4B0F2DD7237930150C46EF0EF77A601FA6884BC5034229C31DD1B15B32198A207AEE4283B8FD7B0ED7D8E90D4F1D56AA0868742AEA5F7C45F14FA24180AD57EA24C49E49654BBAC52BFDC0B387AB87D7F7B5A2915A582A0C9024C25B5CF6236D154623BAD6710F09D7827F929E9D007FAE38DA4082547A9BD89E06BD245BC458EE8293FFFC76854D57D31C02ADCB9A65833F5356A5DF97F37B567D9F121EC2AB8A75157DAA562B5A1050E067012E1A3F6056B0F2A96927243E811CF5BC02B2792242FECA35BEDA87DFEB5FE8B88311B8494E3CB5F66874A6A2A8309F3AB200D7CF804C2011E2CCC8E7BDCEEE31FEA7AEFA7C32FE4C10A305165787D83D171D490F0A0715D7EE1F9A08AEAACF3E657CD266A8B230994A73E1CF51C78812EC5E42533942299C24A27A91461CBED10D45D80568D80C47D25801DBC7E793EA959B05F9FCE718D6D163570DD0CBA825B8F60D36551BCEB1AD4C96A9383E435BB213EBB2D6BF5DB4B40122ECAB40A7914F598778063BDCBFC6650F0D5AE12CDF033E05C7FEC06460FEB5B0A27E352552D11805B70E64A54E6B1EFA0401BA27799BABAF0AF446AC457C2B1D971DABED75424F2641370DE48E867B33E160ABE90028C7C9F986FF579F8624563C9B361FE124CAE55A8027D920114CAE0A3DFB11EF0CC9BE39A67DB007F65163A60FDDD05092DA0C18577002348A5E155C828908226250ABBB2281E4EDAD34B82331C69AA1F220FD533415A9F1610CAD75FD6D90DAA3C3989CC82144057E5057C382F817D2BC66770AA5015421023957DBB522B21B244FD154A276F0659C5912DBDBBD3C7C2CBC852B619C37C4942BBDEBD51D952BEA136CCD8E41BBEB81BA246295A1114D5F0F9372D734B33BC7EA67C30CE81282F620C8215E7C976900701AAA55A2D6AB832796AD3469034A9213C96994B7D9D715A55E07FA600AF0AC3D39C80177BBB398E594FA6DB48750A4A4D688EEA37D66CF6CC07F833C18DC70CAAB86DECF5355C3BF22FBF58754654BBB80795E49890585CCD7675A43927040CEA6ABE8A389C3727BB8B581026BCB06F1ED3F14F573A4D6EA91A764BE2F28DF0DC52CE0D44594F94EDB71D7132A917A47FD83AEF19B25072D30B5D8DEC84EF12DDCD6EE284E1DECB495FDE0F64115DBA0E4C943B64D35A9E646070CA0A6752A19E985251048D31B915352D602B80F3E092B06EA9121ED1E5DCDF5C94E4803A4B9F2F4B790D037B34C5170497641E0D8DF302643A5E0267F45407AEB8BEE6567CB6FF1A79175F630B55B087AEADF4E624B43C2A70C1214DF35EC464A124EB4E5563577C8B3253F750F2E441960E9CD19F7BE1934D2C5775C49C5E9DFCF5D950CFB67FFEE4691263CDCA897CAB5E91FB7EA3726954976F30E86CA10241B1CCB647A4FD1580C07E195F208E8AEDC1DBDFBE365D8FEC974BE85DCCB68C0A437AD85A725DC19E45DF90ABB894EB46A5631E6218FF64BC7A4C381618229D01618181B48DCC084ECA428B21562F1D2EB57FF20DAB4B1E4F9F9D729B7FBE2028B72C63468C8D8A07B395F718EFB32263D066C5B348E6231EB1842A167B9FAAD877EA76D573D3E784CE72F397944F8CDF8B7C82486B04469F2DF2DA76FD855BB74537067788A67ED4D4768F54C9E814E09AD8A3CA827DB54333C3B1B66C39D69B17DC95B961179EC5542A0F3DF5B1DCB5118AFCC36DB9EC33E5286B1466E4EA466517C154327CABB3299E6AB9A7626F98CD6E8B57D37E3CAB1013B1D3C70A609D17D1F79F033E751366D1186DC8202DB0F3F75EF143C886B207771977FC33F9B6CF53D382962F4342F589FABC91D91637C0F5F08F6AED24F1AB7E58130DCD7B0650E8539FFEEF9C30A188FE3A66708CCBCCCFC78B0644E069C33EF6F2A5502F4A1B2171A4814E025D655394D1357CECF35C7FA42CCF488B99554045001FDE37C4CADE11D957C35F859179855418B2A2C4C9B22F244E7E7036A323CFD7B6D7DA54619221432572ED30781D7A7A3BBDB43FA42A3B001AC0CF13C59A85E2CA8A436CDD0378FD58D52D45E79A2D3443375327B7EBFCB673525D8D665453A026556960BD0EDE04F31BDB613725D0550DDDA09F3DC41713FB66B8D4FF50D13FB1BA10A52C4C6145C4EB8329D752AF9976408280B445D767FC3974FC9D09515FED175A797CD6EC39FA442CABCB3CB25244D0C070A9DDC7185E65258A7DA928B72957CEDF8CC06E319BD3E749E97A8D5C6D8F70BD9638C79F6C30B2B108A4F0D9BCD6F5A342909C0FB6C9D72128619933ABEE04830AFDA2C29E531C28EA929A60BE839F65DBBE63CFD317F8A4A602B3EF5414370F8DD31F11F4C08E25E124A2E9D65E22E68A87303EA2997728EA88020D1AC57A04F933C49130FC7937E6D064AAC6F7A94D0E5087FA8CBFB8FBDF4CA5E654AF97BFA8B7A4651B18163E593E9D3F082067BD5ECAE635214331F069E03E0EC6D25DF299C48B7CC7B9EA88D4831BBB88AEE9C6723503D774007DB534FAE672838684525DED851FD72D4E900174F44417AD3EE6A7161EBD05A2BC21B84C7ED7EDEDED17B669A1432DC87A5794D2FC8C82600CDA527BEE3A5EEB4CCDCA7C015135F51CA6979B57E699FDC72EF8077DE9AA806411EFAA79B7C70AFC412E56A1670161577CE690910291D93ACED275231250C5F532AA3075289EE323983E650D8048BE7B426291F515C638051C4D5D356F5CA87BD47320977513208E04C09D4B0B80715D77A16FCAC19ECD64D89F0DF77444A926790E40A025F3ECC902EADDABE0663B67B6F4B0C6BD55F34C43D30C6D1C6D296FD8D131DC2426E2FE54960D230E2CD733C3CBB330D5D6057063D7A9A62B1EF8EE7F63438AFC1A6AA964237711C8FCC6AB40CD24B31B1C5386FEBA9E59D39D0A6E2321809694AE83CD2B25C051CA5A9792A58D5E3AE0E193495D2916DA0FE6E1EA719DBFBA98CDEE455684554420437B5A633F70E6A6DEDEA350648E4C0B2228A3DDD7C51A46545548408ACE33E26A30A3CFC5B0995F4EA49DD998558A5AA3944A5150999A424158C20A14671A4BB25338F56795C018D3DACB2DD664A12072EE124AEDD071FBC254AEC3AF7FB120210ED374DE3927E89035391793DB4AD77A95F42A5A3B8875AEBA06B955535BBA2511AA90F8631D35F3980BFA5095E882C334B92998807D1C4B08C5980C69B9AC06DB5B7014BFC69F2C82523B03235734B6FA8EADFD4F0CDE5CACCA6619D1F76041D1BFD597697C59FC0FA13C9394A78E3BDC396F898A8EC1AE18E7FBF4113A84CFDF5A7EA0FD08BF98894D993F88D753529AF9650855E7C6336532EF86D35795402F3DED32F1ABDABA96F8187AE541CAEE46AB20EE5CCDC29981CF3CEBBB533B65C63EBF3ABA9E19AB1D18749F92ADC917D0879252F10930EDF13A0D7A594E8852FB676FDDF3FF682F3A224E3B5E3107CBF206D2788EA3E691922E9CD828F9EF772F4A4323BFBC33FA85D0EAD278F64F57575245BD8DBE3DAE64A574EA5549F3A7494AD10ABF1E99649A68A218E0997AE08B6273076F0BB10652ECF0B81093DFC2E0A25546A22E2484D25E9047DCA77639274B4D935B521D5A794D45B2BFE06B165B65BA60DB58A3E096D50889AA7E9FD15D83B82736702A3F089015BA35011B4C74171ADE6053123EEA42454585576E515DE22EBE1FA607BB9265B0A7B712655CB0D815FA57BFF9FD753941337AE806283210EA374E7CD87D5D4C963F4DCC9F49142F9FCB4588DC7149C2FF0937F6DBD12BF2C3456BC750DA477A13CC7C2A22B6670B4489C5B15749551620A472FF8133EFD87EFD31FB8EED27604671F0C225E76AB78A99D7D2CB61D8E846626C1E38DC6D1DCFB2578FB5165E74CE60B249CA866BC22BD2FCE9B9953247FC8DAE2659EC4A444B1127B14E30275F198F939F1CAEA5D3398AD72DB3ED60EDAECA689903EA3FC7FDA3D46BD44345FEE86866A24DC59FB230F47D64E9FD7F460E46795112BC75D6B9593CA3F1DD6414F59E08E1B13691FB280ACB60E55618D359AC83657E84C1B974AFAA4E9E91B7E1701BC861F817D6B708FC6A350B8635E79867F34A72C8FEAF69D8CD96854D2770FF53157902C15A5F61B7F723DEFC7AB32D6B91FEDE5091FC3481A1A4B30DAA803731E1464EE7601E562FDA6B2433FD13DA1BC3DFC3457FDF20B435F2A6B68A6154E05A10FF7FD03FD00595E9F06A7EFB7EA7AFCBF56FB2B80379849C9F21E896468E22880ECD6FD75FE5F48324EE16F1F8FEF9BA7B3CD2D7ABC1FB7C4F719E1CC8B206AC2AC40D75CCF1E564C5E8542CD10CCACD1CE829D25C7E14B5621A87BD891EE55B703FD933183996D1B15A6D6D8A71F6287AB9F3DEE297CD9F67C10A356F878BC2D87EB1CE6C079A25A489447A48C61A5CD37D72D419AD0880AE9E8538047E3E732ED253400B5BBFF18FD8296BEC82985826A86D5B85C4029981C74179CECF875E849DD7EBD0EEE3CF73232366435D752835930D44B539BE02B26A0CAD7F4BC88B3D3B3FB9F15168A4EB2419A1C2260480A80F91F551567CB81251719BBDCA5E1F1EA3975414F10777055180CF903476394527AF3D8BD503A6322917C3B070583AD7550620C254AB22DE1CD287127A77406B3C0C95EDDA1634B9EBF1A5F07514043D859388649009D81E02F927A30D70812E3B535838E55CAEBF572963630AFED1F6121DA50B4FE2A4A50F28EF1E97D733B82E53F5A98686BB36D15379B9FB93D8CD05565B8D995FF2825807BA38C672CACCD3A958B1B32DED5B14F020A5E1196B56B2CA4E8DB3612FA9D096F1CF0A00579E4B5A51803C3B281F3591C30E26CE8998BA081F1723D747397AC9F39BB92BB9A7E89508DC218D7A0671FCD171C6E22B37CDCEDE218A4386EC9FC5B1DA0AD73DBFB7414FBCE24F8650E1DD61AA9DD6DDC319BD917B95C05E723A5A7591584D22BB8E549A35B4748E4EA33B9EA7CA282C7D002CB059B7DD619209E30748AA0554991CD8886305C804CC833D2DE627C4B361D7A785026321690227AACB3C589928FDC8BA656E9FB87A9AF64891A5D4170AED2A4408BF8B628D28625B46C2D0EE61095D541FA92ACC8F649F39AFFB229EB00A9D58E956CEB0CCFF0C1A5326153659B5F1718B126B1F0138C62585B08F380ED558D2D2FBA67530966A755A6C4EE6CCD0965E86E7B7C9F36A5BA4B925DCD4B01911EFDA44A600D38367F573B916AC4318FF037B1DE9C55124D1859BE59FD80FC4C6F19EF17C2345F3C4270AFA16D8676C43BE04462B7EA741377813E7D695C5F7A40F900AB38DCF73E7212487F2907B6E07DED89865C88CD582F7026BD11DDBE45CAED84843CE08007E6E315B9551596C145BF65EE16966CC5F1FB78A75A568DC96BB7E67D4FF2D9DF07BE303A71BFF92AFE3771C3787232DA9B30EF777BF136E2EAB94F7B37FCB5ADA8D8386877F2EC19DA22CBADA2D115616B5184B61876F36ED9E6618AE1183378D6D31AB49788BD9F4DF1DB47802DAD82068A8D1C48EC2CBBD13DDF03C99A48C09CA83C41BB18C4BB0FFFA838AB8F1B538E21CD053E78DA68121C27114A5D362A2D1F42A913221E77274A6D90DDBC3DE4414A3A13E565DE1B7F1E09545CD5722A3FCE580DC5C61FF51A9D7473FE6177117AAC251719EA5B68E03AE1918BDE3386DE4304CEBC593E0DF344131DA91F345C903012A1E29ED5FFDD42B927AFA67B29CF16DC6B39185D394360FA61B970D271F92E9BDEC333F60D1B625EA64E5323A2FA67D945CFA1CF1DA9B6CB6FB1FC4467950AF9F9A44E30764D756094C1710847D7C5143275D6DFA3C5047853A839601F56BDB1DAB05815424D8AEB706486CE95CCCF6D5BB12FA23AD41786E6E92C76AF0D2878233B6127170F5963AE2A2885C6F867541DA9FAFE47E224FA936C1BC8E9FA677FF8BBBD354E1AB50EC4FA6B506EBDF99AD12DDB201F126394801F7C7F7341FFD0763ACA0FED23E1A16C35C301D4F22F460F650F8D2C53EBB7B44A71EB6B5CD5B2233A0DAE388DB86B347A07723E80A382B014878E6C60D7943DCA2D2D5861639D69B77536ECFDA83136E13AD3790AC3D7EED740594D9FDE39B056599546D0DEAE8C92D3A28E37FBDC4D122692656B897C2392631038B452C14726804BC209A054C5B65D598B5B70ED392BB3A40BABBF8EF3A35BC1114D89535599341AC899371371894F3016E39000ABF63850C45118954AC84AF47280275357D44758A3ECEF86279433EA1A45C663184667E0098730902179C5786428B2CDC8F10C37EEF8BCA55E6B9F77DF70EF04247F03C5B263499FE01F1BD843EF53920140BDBAEBD26649B3F706649535430DA5654811D777A8BBC6F2B7EE68928FDA9478A471BA404DA6CA5109BA214D5CF46319A88F67032E28EE1FC559BB5B53ED3F0A63AF6498D4A92F88431AF381E23975FAD04E41F2F55200B517AE157C488148FCF6B6BAEF61B6C27C4DF19BE2D28B8805A2188F6BD8173FB56B203356DAC91878FBA2EE5D7D655347E00294DD6DF55D2431B6A857B1214078E9DFFF5DC52E1554F8C11EE6AEC24C56394017639C20B1AF4B5C387FCC4478A8BBA555FA428E19B02A930F675C4A0DD1872210493E0C275A0E6D274E1967F3E63ACA03CA1826287FCC48742AD9E0EC3DF8D72F1326BDFF734B6A9275EE698FA1D989EB03A40665B7D431C545AE524D7D8E69252027FFCB96859155BD8D62B2AA39004DD2E8D3E4B14C932DF2CA02EAD12862552E3946C7AD23ECAC9A820CCC460DEE48C4C8B7C6CB86346DEAECA8E6C14C22B5DDF4F918CCC7D1D2EECF782E8B5A37C879126CA82F9B129118571979D46D36E9C0A1542A56FC1DCE83E22AD56EF9992D24A3997CA1AE7A1E9C9CE55688785936934FAED14818A091D7000EEA6E75C20112201134DC270F405D99D8AA481DF80F296756D41F5697ABF52A2405B6B4C4784105F91DC90B0D800F1CC1A5286BAB1CD796707A908B16913DFA340AD92772D831AC3AC8B7EDD9C6D71A57AE0874CD989A3148EA8C197EBAD946BFCB8231ADC4FBF509DAF95C7EB6C88A3BF4119405491EF37EF6469EB4D2645BE4E3808E5EED5E5FEFAE37A1C149EAA09F312D1FBDC185479372875B6CDF6F72E27268424D10F7AFC09F769EBD0B98B1667CE619EEABA373BFF81C12D6F82C27CF38D539004355F3F6C16A737ED1809AD7CE7C579A49F84610A2F7AF98A0111B1D7547C00325D1E7EC6227A9B37A8DF85887AC8A676372EBDD3D20E5B87F7973E6571B039F353467428700B9F1359466F85E247E73785B6A75CFDC79CA72DB0CDE1234EBCEF35E46F2C15074B5D24DA5CBBD9FB3947943207B0F477237A2C66224CB5B9EC6089AF155E442EF1AB4C56FE4BADE857C3C347FE52579C868F1C02910E3C8BD0EBB3215471C94A30C586A7AFB10F9144B2703CA6459FC4B4AD1F110911EA4AECC5EE880DC20429969997A3C5948338C4E49E5C6748F88878FC5781C18B52E92F5388F3F2C814F06F29E3387B58F31094347DE2594EDD556CB7DBDA737B40DD2D74913BFC3ABB70350AB1E54302742EA5D42C0527D3F7B60E2EC20F00FD49719F98A6C6FB59C5956CF9AE10430E0DB11519862CC961F1432FE15AC4EBFC26E41A33DFC001A77C1CE08B3ECCC358648CDFBA2D4BA9BF061194B21137FF00B4D3B63433C0CE9A502F723EE3A790A620FC57B1F735E552C29F6B787E07A337DFA2FE2804B42CE28EAAFF1E6A260107C5E5EB016655A92C229C8F8FF509ABCAE810F4573C9F64B5B1DE6D8B533EC5DDC0B6B182F852C7B63C2FA86CC6B757822222522820A36444BF98DB4FA5FB8DCD2D3584586A1F9335CEDE3FE844FC040C7FC779BE058C362481315A19146F2D597F2E397E35930C9F069351E9EADBAE0F3C26E9F7DC78B07EF4D843D1A6DCA3CBD28181E329B7F91C51E420963DEEABA79D22A8A6DC51B939B39A6585A89E95E2A8542A4702E7721A8A708BBE53D787B5038378EBF7B76E07657327E93966BD530959808F6E5902053EC53A7C83C05B1283ACB3ECF422FB704B5C6F990F926798D851A34B991B37EEE8DFE080B119AF3DC612E22C918C7DD00221FD77182F420693A5AD0F58921B1F2FDF7DC1B9DF86198E183AB68771D4EA973664B78F4D764A280BA217803902AF8A13B044BEE73781B50F9BCFC118AD705A35A637F2F8B016ABEE08AC8F5990E9CE3B578C4B718DF9BB858D79088D277B3810CB5CB7EE04B3276858D0D3DBFB150ECA6C6B164B37B4C510D50F64BCAC1BCE1CD6824723E86312C804E3F50A99DA8682CC801348BA1CD87C944E54D2168A045BEBD3CEE2678FC7DC83AF0D824D8663FBB5BBB100B712E8FB0CF3B92733145B9D3DD2ABDB71BD58C39550D3ED16CDE767F839DE232CB8EF2FD6283943C2BB635A2F4AC81373E63B2C97E7535445E2C0D14D694B724794317C771CD5D9514F8CCEA776DB7F13B67504E3B706348EAD0E7D6F48FED334A9852AC3657B7A4D57F6D763ACE6865A17466A9B14CD362F062C85DF80988BE862C5F75757FD18C31F2B7FD5D8846FF15901CA69A6E3EBC6DA89E941CEEC7644ECDBE32B432E8775197431CDF1F98B7B72EC3198F1439D9FF9069C770B8EF22FAE73B41FF7D34994FE49BD8A19EEBF5B60A7C83DD7216EE2E44FB298F8EA61446CB25AFCE60F399CD86349CB8977BC869B63658983EC451142DF4A96BF8368BED611D0993344BFA1C4F918A8A4B2E05F45EC2DE96B25F724B8E3AB424975C7E00026907AA02D86CBEB53AF20A709969167805FCD46F342E7B1A019A3FDD939E25BFC957776ACEEBC7F9170124559CC704263078D16A0E8D29ED608DDDBE795E47DB9B0DE06BE9F1505B24772AF692B495BBD05A0AD960E6E0059ADBD181775D465A7F553FDB2AD4BE8E67913434A05BCD710204751A7625D899C59FB526A073D5BDF331BB1B031EE50E81D9ED5BC4476239C7F927EA76C88BC7E9A230F31A98152D8E986D6281988FE4ED3D333A3FF8DEE1895BCFF019114F387A796AFEE067A48C2FBF83400A5BD2A01585BE592926D89C2346897F23408BD5C1DCEB9C5559E6CFA95BF699875ADC1B5B46AE4CC6E9FC7C374C3F209F930409FE480E3A4AC603B114243BE4277CDFE20EB83CEBA7E85DBF23444A1173414A6DBBE6E3E78347DEC3DBA84B063E49F2BD9425E9FAA12E3EA76CDDD2AC538DBB28F02B2104FF2E1A094C2DBBCE9C1347D8F8C93589588CEE1A7DD02057D33295DEEAE3BB18C2B7E61C1FCE34A31C82D89DCCAA4D56947B17616A860B90204E0CAE6936B63D833D96F5D3A754A5BEE9486ED3FF48773CE91BB394D08D481AD792E883307573B44C690C711D208CB81C330E17E84F359479FFEF3F422E0E3283F750AA9BBCA442285D02FD3C26C01AFF2B9675BCC1CE86602CBD0907828695481A024392C2B0B4C9F47714A6F81E12EF7247C820255A79FF51FA71420D1EBA511E8FCF4DA4CE45EF2ECBD81ECB11F923293728B8B9A7D3BDC4BF0F332C7D2436267C421FC2A02005C013E5C1BCE5C515C6F5793B65A686726C40A44BB9942F9CEF9284A2A94FBDABBCA618E21CEAEDE7D6E6057A92AC5DDF785AEB8C05A3EBDC036C593C836D01288F222C50640820FB30EA89BF8743B40EA92ECFBDA5C45336197670E65D2962F5C2E990F848A9FF0EFB1F6D083AA8C1CBD12DDE7E76381BDD5F9F819EE55C84F5E682A0F88CBBEBA000466F70C556B1BFEA24CD579770F27703809D7B0BD03F4419A9A57ACA974A906620338527EB57C9C7C1426DF169AE16F91F9E342547DB03D334646D529B969218FF254C5D0CBE52C3A47E41E43C818954C29D922B98B55B030625FB825227173FCF7F6E1AE656D780D51E3CA74A777EC9F4BB54EC25CF22123374A2115C620200618967907B2D8D899EE0547CF75F7BC2B4440CF94F9A8350B2DE9C3D923E2878B0AD7ED5EA6472F2E807F2B5DE534533E50E5284C22DEAB5EFDAFE1BB29DCE8A684052DE7009B00A94D230C27D1060609A11B770CCF0A76F1BCF543B1AF77528C0E02E0982787CC031E24CDC8B402027B70B368404EA2249DC0431E18EDB9C6442ED2B986B7EC880D90E5EFB52F8259EF4E3C7D0D4E1A708EA5427147917D7A9F0F3157C0C6810B3C2E3BA30A64B6420177814EA1C5B5F69911BA02256A665B0DF150C3FFB62331C54BF0A4BA9CE61FB615CE13A0B070C8F8B33EA3E36C27657BC0ECE3ABEFADBA0ADA8E115BFF4B8A73BB1DBD48E049B2C0CE5687D0535B71E544CBD017693AEDA1F6B413A5CB92757442CBE22A45D3B6BCDF0D29BEC57948F2FA7DDE19E3651C02C81CE14773D3D635688299D7CEFA53481D9D448AFE1895F7AD78D779A7510F4FBBB163EA24B052598388A9DD51D7B42BC1E04D81432428222E1BAD212BE57EFDD101966C5CE15AAA4A8232DF55C89598D290C607BA8D5F9F0129FEF0136FDF8456F83265712B477D925694B61CE0A07E1628853D561D5838C255A358F964D90EC038AF3EF3B1557B08974D76753B236B99B5F825730BD17E81627EA6D88F461EC2BDD960947EE254610DD215B6C56EB6D4A15C020AB46C26F984D3108A191AD4BEFD81431F01FF427ED6F6AF9B90C53CDB5BE95B5CEBD8C77C52C4A3FC4AD6730739EAA528CF11B7040294C0C80143E21EA011179599990369CE8DE96F9B155BE3FFC592244D195696A5FE283B2723E17A22FB3D1FF84EDB1A3AC230F517FEB1F24E1FD573813E0384AF7AF2AD437E610DE7E98C0BB62CF44AB8955BFE7DAA3C0499FFD69A22AD81B07FA54E0D99AFEE0F42D2E9F31FC35DD9F2C0F664982227F97C002F9E74AD3D5764DE8B39C73201A88E876CC353D86CFC4F9862EC28F0EC73DB008ADB7380F73026AC2625CD728B1AA997EC2A01BE4BE86D72AACE125B3F2B867C67D8754874E63E5CC67A99AEE5C2C79D164A90F4FBB9770CB56313B251DCC24C1168C7C5C539EBBA0463D5B2FFC5B4F23627924B073A7EC5166A8AA7B0AC019E4D039E640D9CC9DC9CB15A2441906980EF876B1C6507007F645C2A2A12EB049B5F4E8D42C6B6CBD2D186E29806847A71A01790737185A1256AC033A7A5E09E839F51A3E2131795FDF0BCCD4EF99EC2BD05C16395344BBA1901F36D428B71710FC785E07FE6887CE5D6E2DA2A85D0EBE3C2031FE4F8EBD5073B08ABA0BF28156C3425758312ABFDCC0048F9B2FFCECD65205F6718E009E54CC74BAE19E69DF9D43F042D848C9FE68846172C8796D9332786DE0C7C71592CD6BA13A3FAD7FD602CE1EE17BE940EE98329DDBFC9E50DABDB098D45CDB86806AD0F2C8A5D4C789D48155FC8FDB35E8582D84BA5699616BD979D011EF6E9CB71F6B6C47A04E6EE84F3D59790ACA9A1F5B6CB0B1995BBDC16845F86CB438D4026E9E77D7AD93025EF001FE1590BBB2FEE1DDD47EF7C9C2ABDDB217F585044FF032864A9A49EC15B43AD3E25B8AE8AE7E870C2C0377030C9896AAA1D5A53AD3E82555F16480309BF2AC7EA5752A8B39C52936C05F7553A6810099AEFF9CF44DF40EF9A570EB585D71126E45E8B4AF7BE30CB194D056303BC811A18583F872ADF57A4363B9BD1F8068F163237E1254265C86DA13B3A3399BFEF03F6BA315DEF050E239D035E01B5221AFA02BA988CB6C21445D5A3D6605EF13FB0C35B6ABFCD6C6616775C865B4EE049DFD0D7C7AB0E5FFEDCE728653965FB51B90C5508C22A270A9FC6C73A2AC726EB5B9E96D158CAF19D6766FE603E15D7A5952FC83DD5ACC695A834638B060768DCC8E1AA2BC5A3E24F21514A680C9E128A548FBE54FD7D1533672DB36707E4F59EC855F096738D64DF1DC9913053C9D69290895A29CFCBC5A5321ADCF202C85D5EB0A1509BE575DB794EC545A7CCDD32306EE8637ADDE63480C20C7A8017521C4B765B856719ED0770E882B43916E602DEDA05473A332853B358DB101DB1464E54D372C6DD16BCB60838A6981468B99D0E64FDAFF5B668DE2916F0E200338C40D9717E74BE66FEC902824A99E0732A3D0BE9ABA5848EAA1F3F513782E750AF6A7D8885C2A71AB4915181B338872C6D21FA598CDDCA2122454E6AA0B2647B3F70F5A0573F79F95E2F25F39AABF5B692D69764AE39E09462E323A3DF00A490770CD7FDDCBE76D5BE133AD1335E5D38299070B7ABF050636A0B2FDFEB64CC3531973E183A299D362138A28CBA554AD7DB1C8D799D0EE7F7B5ED5970EA87284B424C172317A69D14AD6B20CFEC42971770425B968CF1B49E220C798672258A9F50C1E740E045C6A966681EC58A38C4EDA421D809BB537223208AA37AFF65AEBD4ABF6A2A4C0E1FAA775249564BB3A679217880B8C525137FB62C5418712F8F505D17EF2F9C59317E8A982CFB201542BD522FF0529F508CF23D4FC078A409CA478635087F2FA748911CA89F2D655F5AE1958CECBA2C74F41E6074682DA2A468CA300DAC7355BCFA3E45C0D9445C3D36D1022F58A47DF38097D13C9FC163E0930BF69ED2BE16B983AA17648807BDE34FB22254FF4B1E7710A251464F7201AC7D70036DAB3034AB3C2FB7FFC255A134BE4F5C7FDB3716A6A07955DC0576BCD882BD80D6D096D58C3148F48616DB126F803956DFCB2CF2AF6B9AAA48EEBCE02BDEC2826FFDD3ED8939AF806DFB8BC48157672FA76ADBD6C67C2B760FC5BD08B9042CDFC965E26EC74975BE35AF99B6B1A16D39166D3A76489717ACBE235C3364EBEE2C094FF4D0D825AC5158C69DD937F90FFEBBD5CECA210D5A5AE4E85F027A19B290F12A2709F4EA83F5093A037FF11371995A25EB0DE58FFD795493F12859139DA32CC7A644882B7CCA711E38FF9A7934F43A90ADD9136943DA9BA7A9583E7D001BA6B9440F2688FC77E03864C3199CE82BB9A4E8B6557A0AA84D4F6B3B991A5453856B5C36C5261DEB297B628E11A03284563F650753DF40D30E13C21A89D6EE46B157FB1CECAF820B2BC6A7B9F0DFF1A87E032CBF251561FD30F38967B9A57F2CC795059E140623B45B4DE8CF9434A29272730990127EBD102856FEC37FAAD8ED71712FDBBF600534C3F179710D91342A3A1341488030119209014615FDF049BD5565984384C5D52B3DF24F37001351AB0EC762B8FAEFB0851D0D8166AF4C8043FC7B93B573647DFF8A055E9F70A5B9BBE301BC99FA0865E9E570ED1BDCA6A8DCC0CA46DCB3EAA6EEFA439E72C935C453E215AE18DB1DFA6D3297A94F50161AB1CD4251B26B433152C538188D7109908F0C4CCB2A731C60B935F378CAA715E00FC43C07B92189FD354C93CC3EBAB4A2AAB85F484A2371C8A9CE0395873D98A01DDBBB8E7E839E1DC0B5E2548BC76528E16D2919F40E0DEF1C5A3BE7A6CEDFB354B0B0075249B7F503B5B59F29147EC7E58926106F6A3993DBDA924453077ACFAA0D2161B91614B7FFBC29F3509CDD699880BB03EA4290B28DC7322622033AC410D2836444FEC4EEA39B20803D77D13D452B90A01100377236B67970E5B32A23726130E06654A021B1697E80259E85A5B11DA538C59EB2A9D8937B61268D47331A071089EE4047E0DC99DD4F5236C2C034B3C44315D4BBD98ED977CC6514D5F42AF303399BE8D781B6C6817409E77790C34AE584C5AF0FD1E2E29B8BA07B98898679B7D70BDF9718E29EC98989BA6E0037A61386F7A222ABF2307F5B8C47D4BF3F46E85F45617D10D18423A2E25527D56CD0FAA5868E011DEDF8BEAF470A658D892F7254F84253DB38D04391FC5216202F80D107BAE1E156276AFA10C3C6E41DAED647AD2BD33D90FE01B732205AD1736EF15763AF770480D992E4A02A040A028632EAE600ABA25C7701CE576EB7AE655BE490EFD51A99BA40FB1C88BEA8AD8E96E4E37E1FF4B010553B7D0940815302F2F780B1C7042ED9AF5798D65099501257F8F6526A1C3015B2DC7278596923A21F22A672EC5473157F2B74867163DC6D5DFDFEAF33B824C8E1CC72C4E306506D6AC4DD450DC6E7515315B63DC483ED670C089916EEC0228C4874386A7B930BBA965E740ABB9BDE36989F3E0F015F47539F36D6A11AADA4CA0B27F929777B69AF18A692F8C9E91789B3C0950719CEB1513E236C75EB15C2D257D527C1271C090A5171F53C179FF149FF09CA87E1716D994DF24452D6ABC16277923C883EA67805BB812BE4CEECF8C8C82D0AC7987A608F5094DAAA9DF508DB04A483CA70A218617A23877D54FA88788D645B5871EFB7C57EF111DE70D5D2769F9DD05CC1E5A06D3045BA8B94E63B6241D447B053FDE0B34522E1237A191A4001ECBB57BF7311C3A54FF6563834CE06758A7002A71B1D6D4BD2FFACBEDB739B5EF0CE57A00FD0869F939424049A117730930FEE92B6964A0811100F10F812872F9E20584D9D0517D96D03043F1E88AB50BC24112FC705A3E1D72AEAAA72CA8AE9DD4D9F08300C9F1047F72827433E5B1A57F7ECF8994BC3AA7AF7602DFD6CB01747A86837338E96E2232502AF0AF51D2E6931F65A6A3CC54A83A4DE515D0B69D393DD1E93A59247C6A5062193C0530952BF6634A1ABBA4AE5AD27A201429E8910C96D2FE533D230979F15C0E42212C9CF0B0F7022E7E42654831FEF15A40675C281D5D39BC9A75746D44D8482343FD34841BBD51904FA06C9A0DEE03B192EFFE43B18BC9538A2532AFAB94F04A349312C11C323E5BB8178E326FECF28FCBEDEC35929B1DC6AE60E15797A3E8134B11866D054D30C442CB2F8D81627A5D1A5CA3AB43BBA8A11531C79F687EBB80CB3349B7FE4F13797C177E07957DA88805A6A37C4BDD492362BDD79548388E86EBF3350ED378C5E0D6A778DB73835049695946C832ED6017DA7FA2C54FE907885287B68747E8A9856F8748DBD9EB305847A4A0B12329B30461D577738715A2164C083BF905F84483F5F4CC141C52776268A412F2F75F997B1D8852974A205C71D1FB69C61282977BAA0CED2A156A602EE24B82035D03A1D7AB28D11F30934B06DF1DEE54836CED123E4BACAF358B961E63CDEDEEF2CD11FDB388C3A1E06A42675F94A5FE417E6FF8E9DE37F6481AEF39279AA0E0B9069084076E4E8860B4BFF967690B3335A7105F58A5FFB44D69C7B0CC4E859CE21A8071C5864C6A9BD4BDE38BD976243385BD3F0B013232D34EA188C3539B3CC5ABEFB11DEC0A2CE24C0F02B10DDB2AC6364AB75D62ECF488E80739001A0D9AF588EF6725FB99310FAF19277E79A270B04A9F440D036066362664D0FB74AA157B7B7DADE518332A997A0B372727BB1408AA5A2954F11C84FAA3B762F33ECFB9B19774AA19581D5BA0DBFF6210CA744B2E6591E1DD931C505B2806505A0EE838DBF07B551E902AA55006EA5D6E790C1F1BEFFECA9631707938BF10C17AEB";
$hot_bits_i = 0;
$len_hot_bits = strlen($hot_bits) - 1;
$cut_num = 1;
$hole_cards = explode (";", $hole_cards_string);
$i = 0;
while ($i \n");
$d = 1;
while ($d <= $num_deals) // the main loop of the program
{
//////////////////////////////////////////////////////
// //
// THE SHUFFLE //
// //
//////////////////////////////////////////////////////
/*
fwrite ($run_log, "Here is the original deck: \n");
reset($cards);
for ($i = 0; $i <= 51; $i++)
fwrite ($run_log, $cards[$i]['symbol'] . $cards[$i]['suit'] . " \n");
fwrite ($run_log, " \n");
*/
$j = 1;
while ($j <= $num_shuffles)
{
reset ($cards);
// srand((float)microtime() * 1000000);
// $cards = create_randomized_array ($cards);
shuffle($cards);
$j = ++$j;
} // end while shuffling the cards
//fwrite ($run_log, "Here is the shuffled deck: \n");
//reset($cards);
//for ($i = 0; $i <= 51; $i++)
// fwrite ($run_log, $cards[$i]['symbol'] . $cards[$i]['suit'] . " \n");
//fwrite ($run_log, " \n");
//////////////////////////////////////////////////////
// //
// THE CUT //
// //
//////////////////////////////////////////////////////
if ($hot_bits_i == $len_hot_bits )
$hot_bits_i = 0; // and we'll start the hots bits string over again
else
$hot_bits_i = ++$hot_bits_i;
$hex_num = hexdec($hot_bits[$hot_bits_i]);
$cut_num = $cut_num + $cards[$hex_num]['rank']; // believe the cutnum is indeterminable without knowledge of algorithm and hotbits
// the $cards are shuffled, and then $hotbit random number is used as an index
// to the shuffled array, returning a number between 1 and 13.
if ($cut_num > 50)
$cut_num = $cut_num - 50;
// fwrite ($run_log, "This is the cutnum " . $cut_num . " \n");
reset ($cards);
$i = 0;
while ($i++ <= $cut_num)
{
$shift_card = array_shift($cards);
array_push ($cards, $shift_card);
} // end while cutting the cards by shifting and pushing
//fwrite ($run_log, "Here is the cut deck: \n");
//reset($cards);
//for ($i = 0; $i <= 51; $i++)
// fwrite ($run_log, $cards[$i]['symbol'] . $cards[$i]['suit'] . " \n");
//fwrite ($run_log, " \n");
//////////////////////////////////////////////////////
// //
// THE DEAL //
// //
//////////////////////////////////////////////////////
$i = 0;
$j = 1;
reset ($cards);
while ($j <= $num_seats)
{
$hand[$j]['hole1_symbol'] = $cards[$i]['symbol'];
$hand[$j]['hole1_suit'] = $cards[$i]['suit'];
$hand[$j]['hole1_rank'] = $cards[$i]['rank'];
$i = ++$i;
$hand[$j]['hole2_symbol'] = $cards[$i]['symbol'];
$hand[$j]['hole2_suit'] = $cards[$i]['suit'];
$hand[$j]['hole2_rank'] = $cards[$i]['rank'];
if ($hand[$j]['hole1_rank'] < $hand[$j]['hole2_rank']) // let's swap them so the higher hole card is first
{
$scr1 = $hand[$j]['hole1_symbol'];
$scr2 = $hand[$j]['hole1_suit'];
$scr3 = $hand[$j]['hole1_rank'];
$hand[$j]['hole1_symbol'] = $hand[$j]['hole2_symbol'];
$hand[$j]['hole1_suit'] = $hand[$j]['hole2_suit'];
$hand[$j]['hole1_rank'] = $hand[$j]['hole2_rank'];
$hand[$j]['hole2_symbol'] = $scr1;
$hand[$j]['hole2_suit'] = $scr2;
$hand[$j]['hole2_rank'] = $scr3;
} // end if swapping hole cards so higher is first
if ($hand[$j]['hole1_suit'] == $hand[$j]['hole2_suit']) // we need to build a generic 'hole_cards', eg, AKs
$hand[$j]['holes_suited'] = "s";
else
$hand[$j]['holes_suited'] = "";
$hand[$j]['hole_cards'] = $hand[$j]['hole1_symbol'] . $hand[$j]['hole2_symbol'] . $hand[$j]['holes_suited'];
$i = ++$i;
$j = ++$j;
} // end while dealing out the hands
$burn1['symbol'] = $cards[$i]['symbol'];
$burn1['suit'] = $cards[$i]['suit'];
$i = ++$i;
$flop1['symbol'] = $cards[$i]['symbol'];
$flop1['suit'] = $cards[$i]['suit'];
$flop1['rank'] = $cards[$i]['rank'];
$i = ++$i;
$flop2['symbol'] = $cards[$i]['symbol'];
$flop2['suit'] = $cards[$i]['suit'];
$flop2['rank'] = $cards[$i]['rank'];
$i = ++$i;
$flop3['symbol'] = $cards[$i]['symbol'];
$flop3['suit'] = $cards[$i]['suit'];
$flop3['rank'] = $cards[$i]['rank'];
$i = ++$i;
$burn2['symbol'] = $cards[$i]['symbol'];
$burn2['suit'] = $cards[$i]['suit'];
$i = ++$i;
$turn['symbol'] = $cards[$i]['symbol'];
$turn['suit'] = $cards[$i]['suit'];
$turn['rank'] = $cards[$i]['rank'];
$i = ++$i;
$burn3['symbol'] = $cards[$i]['symbol'];
$burn3['suit'] = $cards[$i]['suit'];
$i = ++$i;
$river['symbol'] = $cards[$i]['symbol'];
$river['suit'] = $cards[$i]['suit'];
$river['rank'] = $cards[$i]['rank'];
$board[1]['symbol'] = $flop1['symbol'];
$board[1]['suit'] = $flop1['suit'];
$board[1]['rank'] = $flop1['rank'];
$board[2]['symbol'] = $flop2['symbol'];
$board[2]['suit'] = $flop2['suit'];
$board[2]['rank'] = $flop2['rank'];
$board[3]['symbol'] = $flop3['symbol'];
$board[3]['suit'] = $flop3['suit'];
$board[3]['rank'] = $flop3['rank'];
$board[4]['symbol'] = $turn['symbol'];
$board[4]['suit'] = $turn['suit'];
$board[4]['rank'] = $turn['rank'];
$board[5]['symbol'] = $river['symbol'];
$board[5]['suit'] = $river['suit'];
$board[5]['rank'] = $river['rank'];
/*
// The following sorts the board into descending order
$n_ranks = 15;
$k = 0;
while (--$n_ranks >= 1)
{
$n_cards = 0;
while (++$n_cards <= 5)
{
if ($board[$n_cards]['rank'] == $n_ranks)
{
$k = ++$k;
$b[$k]['symbol'] = $board[$n_cards]['symbol'];
$b[$k]['suit'] = $board[$n_cards]['suit'];
} // end if
} // end while
} // end while
$i = 1;
$board_string = "";
while ($i <= 5)
{
$board_string .= $b[$i]['symbol'] . $b[$i]['suit'] . " ";
$i = ++$i;
} // builds the board string used for the run log
*/
//////////////////////////////////////////////////////
// //
// CALCULATING THE HAND //
// //
//////////////////////////////////////////////////////
$j = 1;
while ($j <= $num_seats)
{
$c[1]['symbol'] = $hand[$j]['hole1_symbol']; // first we build an array, $c, of seven cards
$c[1]['suit'] = $hand[$j]['hole1_suit'];
$c[1]['rank'] = $hand[$j]['hole1_rank'];
$c[2]['symbol'] = $hand[$j]['hole2_symbol'];
$c[2]['suit'] = $hand[$j]['hole2_suit'];
$c[2]['rank'] = $hand[$j]['hole2_rank'];
$c[3]['symbol'] = $flop1['symbol'];
$c[3]['suit'] = $flop1['suit'];
$c[3]['rank'] = $flop1['rank'];
$c[4]['symbol'] = $flop2['symbol'];
$c[4]['suit'] = $flop2['suit'];
$c[4]['rank'] = $flop2['rank'];
$c[5]['symbol'] = $flop3['symbol'];
$c[5]['suit'] = $flop3['suit'];
$c[5]['rank'] = $flop3['rank'];
$c[6]['symbol'] = $turn['symbol'];
$c[6]['suit'] = $turn['suit'];
$c[6]['rank'] = $turn['rank'];
$c[7]['symbol'] = $river['symbol'];
$c[7]['suit'] = $river['suit'];
$c[7]['rank'] = $river['rank'];
// The following sorts the cards into descending order
$n_ranks = 15;
$k = 0;
while (--$n_ranks >= 1)
{
$n_cards = 0;
while (++$n_cards <= 7)
{
if ($c[$n_cards]['rank'] == $n_ranks)
{
$k = ++$k;
$s[$k]['symbol'] = $c[$n_cards]['symbol'];
$s[$k]['suit'] = $c[$n_cards]['suit'];
$s[$k]['rank'] = $c[$n_cards]['rank'];
} // end if
} // end while
} // end while
$i = 1;
reset ($s);
$hand[$j]['seven_cards'] = "";
while ($i <= 7)
{
$hand[$j]['seven_cards'] .= $s[$i]['symbol'] . $s[$i]['suit'] . " ";
$i = ++$i;
} // builds the seven cards for each seat
$board = $flop1['symbol'] . $flop1['suit'] . " " .
$flop2['symbol'] . $flop2['suit'] . " " .
$flop3['symbol'] . $flop3['suit'] . " " .
$turn['symbol'] . $turn['suit'] . " " .
$river['symbol'] . $river['suit'] . " ";
/*
fwrite ($run_log, "tcsorted = " .
$s[1]['symbol'] . $s[1]['suit'] . " " .
$s[2]['symbol'] . $s[2]['suit'] . " " .
$s[3]['symbol'] . $s[3]['suit'] . " " .
$s[4]['symbol'] . $s[4]['suit'] . " " .
$s[5]['symbol'] . $s[5]['suit'] . " " .
$s[6]['symbol'] . $s[6]['suit'] . " " .
$s[7]['symbol'] . $s[7]['suit'] . " \n ");
*/
$hand[$j]['kind_string'] = "";
reset ($s);
$i = 1;
while ($i <= 7)
{
$hand[$j]['kind_string'] .= $s[$i]['symbol'];
$i = ++$i;
} // building the kind string
// fwrite ($run_log, "This is the s kind string = " . $s['kind_string'] . " \n");
$hand[$j]['straight_flush'] = "";
$hand[$j]['straight_flush_rank'] = 0;
$hand[$j]['four_kind'] = "";
$hand[$j]['four_kind_rank'] = 0;
$hand[$j]['full_house'] = "";
$hand[$j]['full_house_rank'] = 0;
$hand[$j]['flush'] = "";
$hand[$j]['flush_suit'] = "";
$hand[$j]['flush_rank'] = 0;
$hand[$j]['straight'] = "";
$hand[$j]['straight_rank'] = 0;
$hand[$j]['three_kind'] = "";
$hand[$j]['three_kind_rank'] = 0;
$hand[$j]['two_pairs'] = "";
$hand[$j]['two_pairs_rank'] = 0;
$hand[$j]['one_pair'] = "";
$hand[$j]['one_pair_rank'] = 0;
$hand[$j]['high_card'] = "";
$hand[$j]['high_card_rank'] = 0;
$hand[$j]['num_kicker_wins'] = 0;
$hand[$j]['kicker_win'] = false;
$hand[$j]['result'] = "";
$hand[$j]['has_top_val'] = false;
$hand[$j]['highest_rank'] = 0;
$hand[$j]['best_hand'] = "";
$kicker_win = false;
$hand[$j]['kicker_1'] = "";
$hand[$j]['kicker_1_rank'] = 0;
$hand[$j]['kicker_2'] = "";
$hand[$j]['kicker_2_rank'] = 0;
$hand[$j]['kicker_3'] = "";
$hand[$j]['kicker_3_rank'] = 0;
$hand[$j]['kicker_4'] = "";
$hand[$j]['kicker_4_rank'] = 0;
if (is_flush($hand, $j)) // also figures out straight flushes, which uses a different algorithm than is straight
$happy = $glad;
elseif (is_four_kind ($hand, $j))
$happy = $glad;
elseif (is_straight($hand, $j))
$happy = $glad;
elseif (is_three_kind ($hand, $j)) // also figures out full houses
$happy = $glad;
elseif (is_two_pairs ($hand, $j))
$happy = $glad;
elseif (is_one_pair ($hand, $j))
$happy = $glad;
elseif (is_high_card ($hand, $j))
$happy = $glad;
$j = ++$j;
} // end while calculating the hand
//////////////////////////////////////////////////////
// //
// THE SHOWDOWN //
// //
//////////////////////////////////////////////////////
reset($hand);
$j = 1;
while ($j <= $num_seats) // calculate the highest rank of each hand
{
$best_hand = "";
$high_val = 310;
$hand[$j]['has_top_val'] = false;
if ($hand[$j]['high_card_rank'] > 0)
{
$high_val = $hand[$j]['high_card_rank'];
$best_hand = "high card, " . $hand[$j]['high_card']; // WARNING !!
} // end if
if ($hand[$j]['one_pair_rank'] > 0)
{
$high_val = $hand[$j]['one_pair_rank'];
$best_hand = "one pair, " . $hand[$j]['one_pair']; // DO NOT CHANGE THESE
} // end if
if ($hand[$j]['two_pairs_rank'] > 0)
{
$high_val = $hand[$j]['two_pairs_rank'];
$best_hand = "two pairs, " . $hand[$j]['two_pairs']; // WITHOUT CHANGING THE RESULTS MODULE BELOW
} // end if
if ($hand[$j]['three_kind_rank'] > 0)
{
$high_val = $hand[$j]['three_kind_rank'];
$best_hand = "three of a kind, " . $hand[$j]['three_kind'];
} // end if
if ($hand[$j]['straight_rank']> 0)
{
$high_val = $hand[$j]['straight_rank'];
$best_hand = "a straight, " . $hand[$j]['straight'];
} // end if
if ($hand[$j]['flush_rank'] > 0)
{
$high_val = $hand[$j]['flush_rank'];
$best_hand = "a flush, " . $hand[$j]['flush'] . $hand[$j]['flush_suit']; // WARNING
} // end if
if ($hand[$j]['full_house_rank'] > 0)
{
$high_val = $hand[$j]['full_house_rank'];
$best_hand = "a full house, " . $hand[$j]['full_house']; // DO NOT CHANGE THESE
} // end if
if ($hand[$j]['four_kind_rank']> 0)
{
$high_val = $hand[$j]['four_kind_rank'];
$best_hand = "four of a kind, " . $hand[$j]['four_kind']; // WITHOUT CHANGING RESULTS MODULE BELOW
} // end if
if ($hand[$j]['straight_flush_rank'] > 0)
{
$high_val = $hand[$j]['straight_flush_rank'];
$best_hand = "a straight flush, " . $hand[$j]['straight_flush'] . $hand[$j]['flush_suit'];
} // end if
// fwrite ($run_log, "Best hand for seat: " . $j . " is = " . $best_hand . " v: " . $high_val . " \n ");
$hand[$j]['highest_rank'] = $high_val;
$hand[$j]['best_hand'] = $best_hand;
$j = ++$j;
} // end while calculating the highest rank of each hand
reset($hand);
$j = 1;
$top_val = 310; // this is the rank of high card 7, the worst hand ever
while ($j <= $num_seats) // find the rank of the top hand(s)
{
if ($hand[$j]['highest_rank'] < $top_val) // because the top value is 1, for royal flush
$top_val = $hand[$j]['highest_rank'];
$j = ++$j;
} // end while finding the rank of the top hand(s)
reset($hand);
$j = 1; // do it again, because there may be more than one top hand; i.e., a tie
$num_top_hands = 0;
while ($j <= $num_seats) // mark and count the top hand(s)
{
if ($hand[$j]['highest_rank'] == $top_val)
{
$hand[$j]['has_top_val'] = true;
$num_top_hands = ++$num_top_hands;
} // end if hand has top val
$j = ++$j;
} // end while marking the top hand(s)
reset($hand);
$j = 1;
while ($j <= $num_seats) // to declare winner(s) and ties, if any
{
if ($hand[$j]['has_top_val'] == true)
{
if ($num_top_hands > 1)
{
if (substr_count($hand[$j]['best_hand'], "a flush") > 0) // THIS IS THE RESULTS MODULE
get_top_flush ($hand);
elseif (substr_count($hand[$j]['best_hand'], "four of a kind") > 0)
get_top_three_kind ($hand);
elseif (substr_count($hand[$j]['best_hand'], "three of a kind") > 0)
get_top_three_kind ($hand);
elseif (substr_count($hand[$j]['best_hand'], "two pairs") > 0)
get_top_two_pairs ($hand);
elseif (substr_count($hand[$j]['best_hand'], "one pair") > 0)
get_top_one_pair ($hand);
elseif (substr_count($hand[$j]['best_hand'], "high card") > 0)
get_top_high_card ($hand);
else
$hand[$j]['result'] = "Ties with " . $hand[$j]['best_hand'];
} // end if there is a tie
else // there's only one winner
$hand[$j]['result'] = "Wins with " . $hand[$j]['best_hand'];
} // end if hand has top value
else
$hand[$j]['result'] = "Loses.";
// Now we'll update the results array using the hole cards as key values
$hc = $hand[$j]['hole_cards']; // just an abbreviated name for convenience
$results[$hc]['num_dealt'] = ++$results[$hc]['num_dealt'];
if (substr_count($hand[$j]['result'], "Wins") > 0)
{
$results[$hc]['num_wins'] = ++$results[$hc]['num_wins'];
if ($kicker_win == true)
$results[$hc]['num_kicker_wins'] = ++$results[$hc]['num_kicker_wins'];
if (substr_count($hand[$j]['result'], "straight flush") > 0)
{
$results[$hc]['num_SF_wins'] = ++$results[$hc]['num_SF_wins'];
$results[$hc]['num_SF_reveal'] = $results[$hc]['num_SF_reveal'] + get_reveal ($hand, $j);
} // end if straight flush
elseif (substr_count($hand[$j]['result'], "four of a kind") > 0)
{
$results[$hc]['num_4_wins'] = ++$results[$hc]['num_4_wins'];
$results[$hc]['num_4_reveal'] = $results[$hc]['num_4_reveal'] + get_reveal ($hand, $j);
} // end if four of a kind
elseif (substr_count($hand[$j]['result'], "full house") > 0)
{
$results[$hc]['num_FH_wins'] = ++$results[$hc]['num_FH_wins'];
$results[$hc]['num_FH_reveal'] = $results[$hc]['num_FH_reveal'] + get_reveal ($hand, $j);
} // end if full house
elseif (substr_count($hand[$j]['result'], "flush") > 0)
{
$results[$hc]['num_Fl_wins'] = ++$results[$hc]['num_Fl_wins'];
$results[$hc]['num_Fl_reveal'] = $results[$hc]['num_Fl_reveal'] + get_reveal ($hand, $j);
} // end if flush
elseif (substr_count($hand[$j]['result'], "straight") > 0)
{
$results[$hc]['num_St_wins'] = ++$results[$hc]['num_St_wins'];
$results[$hc]['num_St_reveal'] = $results[$hc]['num_St_reveal'] + get_reveal ($hand, $j);
} // end if straight
elseif (substr_count($hand[$j]['result'], "three of a kind") > 0)
{
$results[$hc]['num_3_wins'] = ++$results[$hc]['num_3_wins'];
$results[$hc]['num_3_reveal'] = $results[$hc]['num_3_reveal'] + get_reveal ($hand, $j);
} // end if three of a kind
elseif (substr_count($hand[$j]['result'], "two pairs") > 0)
{
$results[$hc]['num_2P_wins'] = ++$results[$hc]['num_2P_wins'];
$results[$hc]['num_2P_reveal'] = $results[$hc]['num_2P_reveal'] + get_reveal ($hand, $j);
} // end if two pairs
elseif (substr_count($hand[$j]['result'], "one pair") > 0)
{
$results[$hc]['num_1P_wins'] = ++$results[$hc]['num_1P_wins'];
$results[$hc]['num_1P_reveal'] = $results[$hc]['num_1P_reveal'] + get_reveal ($hand, $j);
} // end if one pair
elseif (substr_count($hand[$j]['result'], "high card") > 0)
$results[$hc]['num_HC_wins'] = ++$results[$hc]['num_HC_wins'];
} // end if wins
elseif (substr_count($hand[$j]['result'], "Ties") > 0)
$results[$hc]['num_ties'] = ++$results[$hc]['num_ties'];
elseif (substr_count($hand[$j]['result'], "Loses") > 0)
$results[$hc]['num_losses'] = ++$results[$hc]['num_losses'];
$j = ++$j;
} // end while declaring winner(s) and ties, if any
if ($debugging_script)
write_out_hand_results_to_run_log ($hand, $d, $board);
$d = ++$d;
} // end while dealing, the main loop of the program
fwrite ($run_log, " \n Here are the results of this execution: \n");
reset ($results);
foreach ($results as $key => $val)
{
fwrite ($run_log, "Cards: " . $results[$key]['hole_cards']);
if (strlen($results[$key]['hole_cards']) == 2)
fwrite ($run_log, "....");
else
fwrite ($run_log, "...");
fwrite ($run_log, "Dealt:" . $results[$key]['num_dealt'] . "...");
fwrite ($run_log, "% dealt:" . (($results[$key]['num_dealt']/$num_deals) * 10) . "...");
fwrite ($run_log, "Wins:" . $results[$key]['num_wins'] . "...");
fwrite ($run_log, "Ties:" . $results[$key]['num_ties'] . "...");
fwrite ($run_log, "Losses:" . $results[$key]['num_losses'] . "...");
fwrite ($run_log, "Wins: SF:" . $results[$key]['num_SF_wins'] . "...");
fwrite ($run_log, "4:" . $results[$key]['num_4_wins'] . "...");
fwrite ($run_log, "FH:" . $results[$key]['num_FH_wins'] . "...");
fwrite ($run_log, "Fl:" . $results[$key]['num_Fl_wins'] . "...");
fwrite ($run_log, "St:" . $results[$key]['num_St_wins'] . "...");
fwrite ($run_log, "3:" . $results[$key]['num_3_wins'] . "...");
fwrite ($run_log, "2P:" . $results[$key]['num_2P_wins'] . "...");
fwrite ($run_log, "1P:" . $results[$key]['num_1P_wins'] . "...");
fwrite ($run_log, "HC:" . $results[$key]['num_HC_wins'] . " \n");
} // end foreach
fwrite ($run_log, " \n \n============================================================================ \n");
$end_time = date("F j, Y, H:i:s");
fwrite ($run_log, "End time was ===" . $end_time . "=== \n \n");
$exec_time = array_sum(explode(' ', microtime())) - $start_time_in_seconds;
fwrite ($run_log, "Execution time was exactly ===" . $exec_time . "=== seconds. \n \n");
$seconds = round($exec_time);
$hours = 0;
$minutes = 0;
if ($seconds > 60)
{
$minutes = floor($seconds / 60); // floor is a function for rounding down
$seconds = $seconds - ($minutes * 60);
if ($minutes > 60)
{
$hours = floor ($minutes / 60);
$minutes = $minutes - ($hours * 60);
} // end if more than 60 minutes
} // end if more than 60 seconds
$execution_time = " " . $hours . ":" . $minutes . ":" . $seconds . " H:m:s";
fwrite ($run_log, "Rounded execution time was " . $execution_time . " in Hours:Minutes:Seconds. \n \n");
fwrite ($run_log, " \n \n============================================================================ \n");
if ($want_log_book)
{
$log_book_name = "Log_book_" . $name_script . "_" . clean_filename (date("F j, Y, H:i:s")) . ".txt"; // opens a look book, where tab delinted results are stored
$log_book = fopen($control_dir . $log_book_name, "w"); // opens a look book, where tab delinted results are stored
fwrite ($log_book, "Cards \tDealt \t Wins \tTies \t Losses\tKicker\t");
fwrite ($log_book, "SF \tReveal \t4 Kind \tReveal\tBoat \tReveal\tFlush \tReveal\tStraight\tReveal\t 3 Kind\tReveal\t");
fwrite ($log_book, "2 Pairs\tReveal\t1 Pair \tReveal\tHi Card\t " . $execution_time . " " . $name_script. " \n");
reset ($results);
foreach ($results as $key => $val)
{
fwrite ($log_book, $results[$key]['hole_cards'] . "\t");
fwrite ($log_book, $results[$key]['num_dealt'] . "\t");
fwrite ($log_book, $results[$key]['num_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_ties'] . "\t");
fwrite ($log_book, $results[$key]['num_losses'] . "\t");
fwrite ($log_book, $results[$key]['num_kicker_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_SF_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_SF_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_4_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_4_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_FH_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_FH_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_Fl_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_Fl_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_St_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_St_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_3_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_3_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_2P_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_2P_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_1P_wins'] . "\t");
fwrite ($log_book, $results[$key]['num_1P_reveal'] . "\t");
fwrite ($log_book, $results[$key]['num_HC_wins'] . "\t \n");
} // end for each result
} // end if want logbook
/*
reset ($results);
$i = 0;
while ($i 0)
{
if ((substr_count($five_flush_string, $flush_suit) == 5) and (substr_count($five_kind_string, $straight_flush) > 0))
$reveal = 5;
elseif ((substr_count($six_flush_string, $flush_suit) >= 5) and (substr_count($six_straight_string, $straight_flush) > 0))
$reveal = 6;
elseif ((substr_count($seven_flush_string, $flush_suit) >= 5) and (substr_count($seven_straight_string, $straight_flush) > 0))
$reveal = 7;
} // end if result is straight flush
elseif (substr_count($hand[$j]['result'], "four of a kind") > 0)
{
$quads = $hand[$j]['four_kind'];
if (substr_count($five_kind_string, $quads) > 0)
$reveal = 5;
elseif (substr_count($six_kind_string, $quads) > 0)
$reveal = 6;
elseif (substr_count($seven_kind_string, $quads) > 0)
$reveal = 7;
} // end if result is 4 kind
elseif (substr_count($hand[$j]['result'], "full house") > 0)
{
$FH = $hand[$j]['full_house'];
$trips = $FH[0] . $FH[1] . $FH[2];
$pair = $FH[3] . $FH[4];
if ((substr_count($five_kind_string, $trips) > 0) and (substr_count($five_kind_string, $pair) > 0))
$reveal = 5;
elseif ((substr_count($six_kind_string, $trips) > 0) and (substr_count($six_kind_string, $pair) > 0))
$reveal = 6;
elseif ((substr_count($seven_kind_string, $trips) > 0) and (substr_count($seven_kind_string, $pair) > 0))
$reveal = 7;
} // end if result is full house
elseif (substr_count($hand[$j]['result'], "flush") > 0)
{
if (substr_count($five_flush_string, $flush_suit) == 5)
$reveal = 5;
elseif (substr_count($six_flush_string, $flush_suit) >= 5)
$reveal = 6;
elseif (substr_count($seven_flush_string, $flush_suit) >= 5)
$reveal = 7;
} // end if result is flush
elseif (substr_count($hand[$j]['result'], "straight") > 0)
{
if (substr_count($five_kind_string, $straight) > 0)
$reveal = 5;
elseif (substr_count($six_straight_string, $straight) > 0)
$reveal = 6;
elseif (substr_count($seven_straight_string, $straight) > 0)
$reveal = 7;
} // end if result is straight
elseif (substr_count($hand[$j]['result'], "three of a kind") > 0)
{
$trips = $hand[$j]['three_kind'];
if (substr_count($five_kind_string, $trips) > 0)
$reveal = 5;
elseif (substr_count($six_kind_string, $trips) > 0)
$reveal = 6;
elseif (substr_count($seven_kind_string, $trips) > 0)
$reveal = 7;
} // end if result is 3 kind
elseif (substr_count($hand[$j]['result'], "two pairs") > 0)
{
$pair1 = $hand[$j]['two_pairs'][0] . $hand[$j]['two_pairs'][1];
$pair2 = $hand[$j]['two_pairs'][2] . $hand[$j]['two_pairs'][3];
if ((substr_count($five_kind_string, $pair1) > 0) and (substr_count($five_kind_string, $pair2) > 0))
$reveal = 5;
elseif ((substr_count($six_kind_string, $pair1) > 0) and (substr_count($six_kind_string, $pair2) > 0))
$reveal = 6;
elseif ((substr_count($seven_kind_string, $pair1) > 0) and (substr_count($seven_kind_string, $pair2) > 0))
$reveal = 7;
} // end if result is 2 pair
elseif (substr_count($hand[$j]['result'], "one pair") > 0)
{
$pair1 = $hand[$j]['one_pair'];
if (substr_count($two_kind_string, $pair1) > 0)
$reveal = 2;
elseif (substr_count($five_kind_string, $pair1) > 0)
$reveal = 5;
elseif (substr_count($six_kind_string, $pair1) > 0)
$reveal = 6;
elseif (substr_count($seven_kind_string, $pair1) > 0)
$reveal = 7;
} // end if result is pair
return ($reveal);
} // end function get reveal
function tc_sort_string ($in_string)
{
global $run_log, $cards_ord;
$new_string = "";
reset ($cards_ord);
$i = 0;
while ($i <= 12)
{
$j = 0;
while ($j <= (strlen($in_string) - 1))
{
if ($in_string[$j] == $cards_ord[$i])
$new_string .= $in_string[$j];
$j = ++$j;
} // end while looking through the in string
$i = ++$i;
} // end while going from aces through deuces
return ($new_string);
} // end function tc_sort_string
function get_percent ($num1, $num2)
{
// Converts two numbers into a percentage, rounded to 3 decimal places
if ($num2 > 0)
$percent = round((($num1 / $num2) * 100), 3);
else
$percent = 0;
return($percent);
} // end function get_percent
function create_randomized_array ($in_array)
{
// This replacement for the shuffle function is drawn from page 230, PHP BIBLE, 2nd Ed., Tim Converse and Jouce Park,
// Wiley Publishing, Inc., 2002. Converse and Park believe this function randomizes more thoroughly than Shuffle.
// Extracted herein for the purposes of research under the Fair Use provisions of the copyright regulations.
$in_array_length = count ($in_array);
$working_array = array ();
for ($i = 0; $i $top_kicker_rank)
$top_kicker_rank = $hand[$j][$kicker_rank];
$j = ++$j;
} // end while
$j = 1;
$num_top_kickers = 0;
while ($j <= $num_seats) // find how many hands have the top kicker
{
if ($hand[$j]['has_top_val'] == true)
if ($hand[$j][$kicker_rank] == $top_kicker_rank)
$num_top_kickers = ++$num_top_kickers;
$j = ++$j;
} // end while
if ($num_top_kickers == 1)
$found_top_kicker = true;
$j = 1;
while ($j <= $num_seats) // read 'em and weep
{
if ($hand[$j]['has_top_val'] == true)
{
if (($hand[$j][$kicker_rank] == $top_kicker_rank) and ($found_top_kicker))
$hand[$j]['result'] = "Wins with " . $hand[$j]['best_hand'] . ", and a kicker of " . $hand[$j][$kicker];
if ($hand[$j][$kicker_rank] < $top_kicker_rank)
$hand[$j]['result'] = "Loses";
if (($hand[$j][$kicker_rank] == $top_kicker_rank) and (!$found_top_kicker) and ($last_kicker))
$hand[$j]['result'] = "Ties with " . $hand[$j]['best_hand'];
} // end if has top value
$j = ++$j;
} // end while reading and weeping
return ($found_top_kicker);
} // end function is top kicker
function get_kickers ($hand, $num_kickers)
{
global $run_log, $hand, $num_seats, $ranks_kicker;
$j = 1;
while ($j <= $num_seats)
{
if ($hand[$j]['has_top_val'] == true)
{
reset ($ranks_kicker);
$hand[$j]['kicker_1'] = $hand[$j]['kicker_string'][0];
$hand[$j]['kicker_1_rank'] = $ranks_kicker[$hand[$j]['kicker_1']]['rank'];
if ($num_kickers > 1)
{
$hand[$j]['kicker_2'] = $hand[$j]['kicker_string'][1];
$hand[$j]['kicker_2_rank'] = $ranks_kicker[$hand[$j]['kicker_2']]['rank'];
} // end if we want kicker 2
if ($num_kickers > 2)
{
$hand[$j]['kicker_3'] = $hand[$j]['kicker_string'][2];
$hand[$j]['kicker_3_rank'] = $ranks_kicker[$hand[$j]['kicker_3']]['rank'];
} // end if we want kicker 3
if ($num_kickers > 3)
{
$hand[$j]['kicker_4'] = $hand[$j]['kicker_string'][3];
$hand[$j]['kicker_4_rank'] = $ranks_kicker[$hand[$j]['kicker_4']]['rank'];;
} // end if we want kicker 4
} // end if hand has top value
$j = ++$j;
} // end while looping through each seat
} // end function get kickers
function get_top_flush ($hand)
{
global $run_log, $hand, $num_seats;
$j = 1;
while ($j <= $num_seats) // find the flush kicker in each flush hand's hole cards
{
if ($hand[$j]['flush_rank'] > 0)
{
if ($hand[$j]['hole1_suit'] == $hand[$j]['flush_suit'])
{
$hand[$j]['flush_kicker_rank'] = $hand[$j]['hole1_rank'];
$hand[$j]['flush_kicker'] = $hand[$j]['hole1_symbol'];
} // end if
elseif ($hand[$j]['hole2_suit'] == $hand[$j]['flush_suit'])
{
$hand[$j]['flush_kicker_rank'] = $hand[$j]['hole2_rank'];
$hand[$j]['flush_kicker'] = $hand[$j]['hole2_symbol'];
} // end elseif the second hole card is the flush kicker
else
{
$hand[$j]['flush_kicker_rank'] = 0;
$hand[$j]['flush_kicker'] = "";
} // end else you got no flush kicker
} // end if this is a flush
$j = ++$j;
} // end while
$j = 1;
$top_flush_kicker_rank = 0;
while ($j <= $num_seats) // find which of the flush kickers is highest
{
if ($hand[$j]['flush_rank'] > 0)
if ($hand[$j]['flush_kicker_rank'] > $top_flush_kicker_rank)
$top_flush_kicker_rank = $hand[$j]['flush_kicker_rank'];
$j = ++$j;
} // end while
$j = 1;
while ($j <= $num_seats) // read 'em and weep
{
if ($hand[$j]['flush_rank'] > 0)
if ($top_flush_kicker_rank == 0)
$hand[$j]['result'] = "This is a flush tie: " . $hand[$j]['best_hand'];
elseif ($hand[$j]['flush_kicker_rank'] == $top_flush_kicker_rank)
$hand[$j]['result'] = "Wins with " . $hand[$j]['best_hand'];
else
$hand[$j]['result'] = "Loses.";
$j = ++$j;
} // end while reading and weeping
} // end function get top flush
function is_flush ($hand, $j)
{
global $run_log, $hand, $j, $ranks_flush;
$is_flush = false;
$is_straight_flush_string = "";
$hand[$j]['flush'] = "";
$num_spades = substr_count($hand[$j]['seven_cards'], "s");
$num_clubs = substr_count($hand[$j]['seven_cards'], "c");
$num_diamonds = substr_count($hand[$j]['seven_cards'], "d");
$num_hearts = substr_count($hand[$j]['seven_cards'], "h");
if ($num_spades >= 5)
{
$is_flush = true;
$hand[$j]['flush_suit'] = "s";
}
elseif ($num_clubs >= 5)
{
$is_flush = true;
$hand[$j]['flush_suit'] = "c";
}
elseif ($num_diamonds >= 5)
{
$is_flush = true;
$hand[$j]['flush_suit'] = "d";
}
elseif ($num_hearts >= 5)
{
$is_flush = true;
$hand[$j]['flush_suit'] = "h";
}
if ($is_flush) // get the flush and check for straight flush
{
$i = 0;
while ($i <= (strlen($hand[$j]['seven_cards']) - 1))
{
if ($hand[$j]['seven_cards'][$i] == $hand[$j]['flush_suit'])
$hand[$j]['flush'] .= $hand[$j]['seven_cards'][$i -1];
$i = ++$i;
} // end while
reset ($ranks_flush);
$hand[$j]['flush_rank'] = $ranks_flush[$hand[$j]['flush'][0]]['rank'];
if (is_straight_flush ($hand, $j)) // need to look for a straight flush BEFORE truncating the flush string
$happy = true;
if (strlen($hand[$j]['flush']) > 5)
$hand[$j]['flush'] = $hand[$j]['flush'][0] . $hand[$j]['flush'][1] . $hand[$j]['flush'][2] . $hand[$j]['flush'][3] . $hand[$j]['flush'][4];
} // end if is flush
return ($is_flush);
} // end function is_flush
function is_straight_flush ($hand, $j)
{
global $run_log, $hand, $j, $ranks_straight_flush;
$is_straight_flush_string = $hand[$j]['flush'];
if (substr_count($is_straight_flush_string, "A") > 0)
$is_straight_flush_string .= "A"; // this is a kludge to allow an Ace low straight to be detected
reset ($ranks_straight_flush);
$found = false;
foreach ($ranks_straight_flush as $key => $val)
if (!$found)
if (substr_count($is_straight_flush_string, $key) > 0)
{
$hand[$j]['straight_flush_rank'] = $ranks_straight_flush[$key]['rank'];
$hand[$j]['straight_flush'] = $key;
$found = true;
} // end if found the first and therefore best straight flush
return ($found);
} // end function is straight flush
function is_four_kind ($hand, $j)
{
global $run_log, $hand, $j, $ranks_four_kind;
$found = false;
reset ($ranks_four_kind);
foreach ($ranks_four_kind as $key => $val)
if (!$found)
if (substr_count($hand[$j]['kind_string'], $key) > 0)
{
$hand[$j]['four_kind_rank'] = $ranks_four_kind[$key]['rank'];
$hand[$j]['four_kind'] = $key;
$found = true;
} // end if found the four kind
return ($found);
} // end function is four kind
function is_full_house ($hand, $j)
{
global $run_log, $hand, $j, $ranks_full_house, $ranks_one_pair;
$short_kind_string = str_replace($hand[$j]['three_kind'], "", $hand[$j]['kind_string']);
$found = false;
reset ($ranks_one_pair);
reset ($ranks_full_house);
foreach ($ranks_one_pair as $key => $val)
if (!$found)
if (substr_count($short_kind_string, $key) > 0)
{
$found = true;
$hand[$j]['full_house'] = $hand[$j]['three_kind'] . $key;
$hand[$j]['full_house_rank'] = $ranks_full_house[$hand[$j]['full_house']]['rank'];
} // end if found the first and therefore best full house
return ($found);
} // end function is full house
function is_straight ($hand, $j)
{
global $run_log, $hand, $j, $ranks_straight;
$straight_string = get_straight_string ($hand[$j]['kind_string']);
$found = false;
reset ($ranks_straight);
foreach ($ranks_straight as $key => $val)
if (!$found)
if (substr_count($straight_string, $key) > 0)
{
$found = true;
$hand[$j]['straight_rank'] = $ranks_straight[$key]['rank'];
$hand[$j]['straight'] = $key;
} // end if found the straight
return ($found);
} // end function is_straight
function get_straight_string ($in_string)
{
global $run_log;
$last_symbol = "";
$straight_string = "";
$i = 0;
while ($i <= (strlen($in_string) -1)) // creates a new string without duplicate symbols
{
if ($in_string[$i] != $last_symbol)
$straight_string .= $in_string[$i];
$last_symbol = $in_string[$i];
$i = ++$i;
} // making the is straight string
if (substr_count($straight_string, "A") > 0)
$straight_string .= "A"; // this is a kludge to allow an Ace low straight to be detected
// fwrite ($run_log, "In get straight string, this is the straight string ===" . $straight_string . "=== \n");
return ($straight_string);
} // end function get_straight string
function is_three_kind ($hand, $j)
{
global $run_log, $hand, $j, $ranks_three_kind;
$found = false;
reset ($ranks_three_kind);
foreach ($ranks_three_kind as $key => $val)
if (!$found)
if (substr_count($hand[$j]['kind_string'], $key) > 0)
{
$found = true;
$hand[$j]['three_kind_rank'] = $ranks_three_kind[$key]['rank'];
$hand[$j]['three_kind'] = $key;
$hand[$j]['kicker_string'] = str_replace($hand[$j]['three_kind'], "", $hand[$j]['kind_string']);
if (is_full_house ($hand, $j))
$happy = true;
} // end if found the three_kind
return ($found);
} // end function is three kind
function is_two_pairs ($hand, $j)
{
global $run_log, $hand, $j, $ranks_one_pair, $ranks_two_pairs, $ranks_kicker;
$found = false;
$first_found = false;
$second_found = false;
reset ($ranks_one_pair);
foreach ($ranks_one_pair as $key => $val)
if (!$found)
if (substr_count($hand[$j]['kind_string'], $key) > 0)
if ($first_found == false)
{
$first_pair = $key;
$first_found = true;
} // end if top pairs found
elseif ($second_found == false)
{
$second_pair = $key;
$second_found = true;
} // end if second pairs is found
if (($first_found == true) and ($second_found == true))
{
$found = true;
$hand[$j]['two_pairs'] = $first_pair . $second_pair;
$hand[$j]['kicker_string'] = str_replace($first_pair, "", $hand[$j]['kind_string']);
$hand[$j]['kicker_string'] = str_replace($second_pair, "", $hand[$j]['kicker_string']);
reset ($ranks_two_pairs);
$hand[$j]['two_pairs_rank'] = $ranks_two_pairs[$hand[$j]['two_pairs']]['rank'];
} // end if two pairs found
return ($found);
} // end function is two pairs
function is_one_pair ($hand, $j)
{
global $run_log, $hand, $j, $ranks_one_pair;
$found = false;
reset ($ranks_one_pair);
foreach ($ranks_one_pair as $key => $val)
if (!$found)
if (substr_count($hand[$j]['kind_string'], $key) > 0)
{
$found = true;
$hand[$j]['one_pair_rank'] = $ranks_one_pair[$key]['rank'];
$hand[$j]['one_pair'] = $key;
$hand[$j]['kicker_string'] = str_replace($hand[$j]['one_pair'], "", $hand[$j]['kind_string']);
} // end if found the one_pair
return ($found);
} // end function is one pair
function is_high_card ($hand, $j)
{
global $run_log, $hand, $j, $ranks_high_card;
$i = 0;
$found = false;
reset ($ranks_high_card);
reset ($ranks_high_card);
foreach ($ranks_high_card as $key => $val)
if (!$found)
if (substr_count($hand[$j]['kind_string'], $key) > 0)
{
$found = true;
$hand[$j]['high_card_rank'] = $ranks_high_card[$key]['rank'];
$hand[$j]['high_card'] = $key;
$hand[$j]['kicker_string'] = str_replace($hand[$j]['high_card'], "", $hand[$j]['kind_string']);
} // end if found the high_card
return ($found);
} // end function is high card
function clean_filename ($filename)
// eliminates redundant spaces and illegal characters in filename
{
global $run_log;
$filename = trim(ereg_replace ("[^a-zA-Z0-9()]", "_", $filename)); // removes characters inappropriate for a filename
$i = 0;
while ($i++ <5)
$filename = str_replace ("__", "_", $filename); // removes double underscores
// fwrite ($run_log, "Here's the filename in clean filename ===" . $filename . "=== \n");
return ($filename);
} // end function clean_filename
function write_out_hand_results_to_run_log ($hand, $d, $board)
{
global $run_log, $hand, $d, $num_seats;
fwrite ($run_log, "Deal " . $d . " \n");
fwrite ($run_log, "Board: " . $board . " \n");
$j = 1;
while ($j <= $num_seats)
{
fwrite ($run_log, "Seat " . $j . ": " . $hand[$j]['hole1_symbol'] . $hand[$j]['hole1_suit'] . " " .
$hand[$j]['hole2_symbol'] . $hand[$j]['hole2_suit'] . "....");
if ($hand[$j]['straight_flush_rank'] > 0)
fwrite ($run_log, " SF: " . $hand[$j]['straight_flush'] . " v:" . $hand[$j]['straight_flush_rank'] . " ");
elseif ($hand[$j]['four_kind_rank'] > 0)
fwrite ($run_log, " 4: " . $hand[$j]['four_kind'] . " v:" . $hand[$j]['four_kind_rank'] . " ");
elseif ($hand[$j]['full_house_rank'] > 0)
fwrite ($run_log, " FH: " . $hand[$j]['full_house'] . " v:" . $hand[$j]['full_house_rank'] . " ");
elseif ($hand[$j]['flush_rank'] > 0)
fwrite ($run_log, " Fl: " . $hand[$j]['flush'] . $hand[$j]['flush_suit'] . " v:" . $hand[$j]['flush_rank'] . " ");
elseif ($hand[$j]['straight_rank'] > 0)
fwrite ($run_log, " St: " . $hand[$j]['straight'] . " v:" . $hand[$j]['straight_rank'] . " ");
elseif ($hand[$j]['three_kind_rank'] > 0)
fwrite ($run_log, " 3: " . $hand[$j]['three_kind'] . " v:" . $hand[$j]['three_kind_rank'] . " ");
elseif ($hand[$j]['two_pairs_rank'] > 0)
fwrite ($run_log, " 2P: " . $hand[$j]['two_pairs'] . " v:" . $hand[$j]['two_pairs_rank'] . " ");
elseif ($hand[$j]['one_pair_rank'] > 0)
fwrite ($run_log, " 1P: " . $hand[$j]['one_pair'] . " v:" . $hand[$j]['one_pair_rank'] . " ");
elseif ($hand[$j]['high_card_rank'] > 0)
fwrite ($run_log, " HC: " . $hand[$j]['high_card'] . " v:" . $hand[$j]['high_card_rank'] . " ");
fwrite ($run_log, "....... Result: " . $hand[$j]['result']);
fwrite ($run_log, " \n ");
$j = ++$j;
} // end while looping through the hands
fwrite ($run_log, " \n \n");
} // end function write out hand results to run log
// simple, actually.
?>
|