Last active
November 19, 2019 08:00
-
-
Save mgritter/9f1f73cdc145e164ea9603e54b9d2be4 to your computer and use it in GitHub Desktop.
LP solver for three-card-poker, one round of limit betting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Starting solver... | |
| 6669 variables | |
| 6669 constraints | |
| hand F CF CC CRF CRC RF RC RR | |
| -------- ------- ------- ------- ------- ------- ------- ------- ------- | |
| AKQs 1.00000 | |
| KQJs 1.00000 | |
| QJTs 1.00000 | |
| JT9s 1.00000 | |
| T98s 1.00000 | |
| 987s 1.00000 | |
| 876s 1.00000 | |
| 765s 1.00000 | |
| 654s 1.00000 | |
| 543s 1.00000 | |
| 432s 1.00000 | |
| AAAo 1.00000 | |
| KKKo 1.00000 | |
| QQQo 1.00000 | |
| JJJo 1.00000 | |
| TTTo 1.00000 | |
| 999o 1.00000 | |
| 888o 1.00000 | |
| 777o 1.00000 | |
| 666o 1.00000 | |
| 555o 1.00000 | |
| 444o 1.00000 | |
| 333o 1.00000 | |
| 222o 1.00000 | |
| AKQo 1.00000 | |
| KQJo 1.00000 | |
| QJTo 1.00000 | |
| JT9o 1.00000 | |
| T98o 0.79878 0.20122 | |
| 987o 0.66444 0.33556 | |
| 876o 0.23389 0.02566 0.74044 | |
| 765o 0.37705 0.62295 | |
| 654o 0.04671 0.66690 0.28638 | |
| 543o 0.24198 0.52064 0.23738 | |
| 432o 0.14349 0.85651 | |
| AKJs 1.00000 | |
| AKTs 1.00000 | |
| AK9s 1.00000 | |
| AK8s 0.33608 0.66392 | |
| AK7s 1.00000 | |
| AK6s 1.00000 | |
| AK5s 1.00000 | |
| AK4s 1.00000 | |
| AK3s 1.00000 | |
| AK2s 1.00000 | |
| AQJs 1.00000 | |
| AQTs 1.00000 | |
| AQ9s 1.00000 | |
| AQ8s 1.00000 | |
| AQ7s 1.00000 | |
| AQ6s 1.00000 | |
| AQ5s 1.00000 | |
| AQ4s 1.00000 | |
| AQ3s 1.00000 | |
| AQ2s 1.00000 | |
| AJTs 1.00000 | |
| AJ9s 1.00000 | |
| AJ8s 1.00000 | |
| AJ7s 1.00000 | |
| AJ6s 1.00000 | |
| AJ5s 1.00000 | |
| AJ4s 1.00000 | |
| AJ3s 1.00000 | |
| AJ2s 1.00000 | |
| AT9s 1.00000 | |
| AT8s 0.13573 0.86427 | |
| AT7s 0.69937 0.30063 | |
| AT6s 0.36892 0.63108 | |
| AT5s 0.34756 0.19378 0.45866 | |
| AT4s 1.00000 | |
| AT3s 1.00000 | |
| AT2s 0.38983 0.61017 | |
| A98s 1.00000 | |
| A97s 1.00000 | |
| A96s 1.00000 | |
| A95s 0.08516 0.91484 | |
| A94s 1.00000 | |
| A93s 1.00000 | |
| A92s 0.64934 0.35066 | |
| A87s 1.00000 | |
| A86s 1.00000 | |
| A85s 1.00000 | |
| A84s 1.00000 | |
| A83s 1.00000 | |
| A82s 1.00000 | |
| A76s 1.00000 | |
| A75s 1.00000 | |
| A74s 1.00000 | |
| A73s 1.00000 | |
| A72s 1.00000 | |
| A65s 1.00000 | |
| A64s 1.00000 | |
| A63s 1.00000 | |
| A62s 1.00000 | |
| A54s 1.00000 | |
| A53s 1.00000 | |
| A52s 1.00000 | |
| A43s 0.38063 0.61937 | |
| A42s 1.00000 | |
| A32s 1.00000 | |
| KQTs 1.00000 | |
| KQ9s 1.00000 | |
| KQ8s 1.00000 | |
| KQ7s 1.00000 | |
| KQ6s 1.00000 | |
| KQ5s 1.00000 | |
| KQ4s 1.00000 | |
| KQ3s 1.00000 | |
| KQ2s 1.00000 | |
| KJTs 1.00000 | |
| KJ9s 1.00000 | |
| KJ8s 1.00000 | |
| KJ7s 1.00000 | |
| KJ6s 0.82202 0.17798 | |
| KJ5s 1.00000 | |
| KJ4s 1.00000 | |
| KJ3s 1.00000 | |
| KJ2s 1.00000 | |
| KT9s 1.00000 | |
| KT8s 1.00000 | |
| KT7s 0.80021 0.19979 | |
| KT6s 0.09532 0.90468 | |
| KT5s 1.00000 | |
| KT4s 1.00000 | |
| KT3s 0.69096 0.30904 | |
| KT2s 1.00000 | |
| K98s 1.00000 | |
| K97s 1.00000 | |
| K96s 1.00000 | |
| K95s 1.00000 | |
| K94s 0.36804 0.63196 | |
| K93s 0.78480 0.21520 | |
| K92s 1.00000 | |
| K87s 0.05290 0.94710 | |
| K86s 1.00000 | |
| K85s 1.00000 | |
| K84s 1.00000 | |
| K83s 1.00000 | |
| K82s 1.00000 | |
| K76s 1.00000 | |
| K75s 1.00000 | |
| K74s 1.00000 | |
| K73s 1.00000 | |
| K72s 1.00000 | |
| K65s 1.00000 | |
| K64s 1.00000 | |
| K63s 1.00000 | |
| K62s 1.00000 | |
| K54s 1.00000 | |
| K53s 1.00000 | |
| K52s 1.00000 | |
| K43s 1.00000 | |
| K42s 1.00000 | |
| K32s 1.00000 | |
| QJ9s 1.00000 | |
| QJ8s 0.03509 0.96491 | |
| QJ7s 1.00000 | |
| QJ6s 1.00000 | |
| QJ5s 1.00000 | |
| QJ4s 1.00000 | |
| QJ3s 1.00000 | |
| QJ2s 0.60934 0.39066 | |
| QT9s 1.00000 | |
| QT8s 1.00000 | |
| QT7s 0.00465 0.99535 | |
| QT6s 1.00000 | |
| QT5s 0.28963 0.56633 0.14405 | |
| QT4s 1.00000 | |
| QT3s 1.00000 | |
| QT2s 0.25354 0.74646 | |
| Q98s 1.00000 | |
| Q97s 1.00000 | |
| Q96s 0.75838 0.24162 | |
| Q95s 1.00000 | |
| Q94s 1.00000 | |
| Q93s 1.00000 | |
| Q92s 1.00000 | |
| Q87s 1.00000 | |
| Q86s 0.09163 0.57181 0.33656 | |
| Q85s 0.71520 0.28480 | |
| Q84s 1.00000 | |
| Q83s 1.00000 | |
| Q82s 1.00000 | |
| Q76s 1.00000 | |
| Q75s 1.00000 | |
| Q74s 1.00000 | |
| Q73s 0.65050 0.34950 | |
| Q72s 1.00000 | |
| Q65s 1.00000 | |
| Q64s 1.00000 | |
| Q63s 1.00000 | |
| Q62s 1.00000 | |
| Q54s 1.00000 | |
| Q53s 1.00000 | |
| Q52s 1.00000 | |
| Q43s 1.00000 | |
| Q42s 1.00000 | |
| Q32s 1.00000 | |
| JT8s 1.00000 | |
| JT7s 0.96945 0.03055 | |
| JT6s 0.60160 0.39840 | |
| JT5s 1.00000 | |
| JT4s 1.00000 | |
| JT3s 1.00000 | |
| JT2s 1.00000 | |
| J98s 1.00000 | |
| J97s 0.69381 0.30619 | |
| J96s 1.00000 | |
| J95s 1.00000 | |
| J94s 1.00000 | |
| J93s 1.00000 | |
| J92s 1.00000 | |
| J87s 1.00000 | |
| J86s 1.00000 | |
| J85s 0.93792 0.06208 | |
| J84s 1.00000 | |
| J83s 0.44785 0.55215 | |
| J82s 1.00000 | |
| J76s 0.70079 0.29921 | |
| J75s 1.00000 | |
| J74s 0.17478 0.82522 | |
| J73s 0.26994 0.73006 | |
| J72s 1.00000 | |
| J65s 1.00000 | |
| J64s 0.61295 0.38705 | |
| J63s 1.00000 | |
| J62s 1.00000 | |
| J54s 0.32853 0.67147 | |
| J53s 1.00000 | |
| J52s 1.00000 | |
| J43s 1.00000 | |
| J42s 1.00000 | |
| J32s 1.00000 | |
| T97s 0.10660 0.89340 | |
| T96s 1.00000 | |
| T95s 1.00000 | |
| T94s 1.00000 | |
| T93s 1.00000 | |
| T92s 1.00000 | |
| T87s 1.00000 | |
| T86s 1.00000 | |
| T85s 1.00000 | |
| T84s 0.53205 0.46795 | |
| T83s 1.00000 | |
| T82s 1.00000 | |
| T76s 1.00000 | |
| T75s 1.00000 | |
| T74s 0.14524 0.85476 | |
| T73s 0.47330 0.52670 | |
| T72s 1.00000 | |
| T65s 1.00000 | |
| T64s 1.00000 | |
| T63s 0.85589 0.14411 | |
| T62s 1.00000 | |
| T54s 1.00000 | |
| T53s 0.63565 0.36435 | |
| T52s 1.00000 | |
| T43s 1.00000 | |
| T42s 1.00000 | |
| T32s 1.00000 | |
| 986s 1.00000 | |
| 985s 0.30854 0.69146 | |
| 984s 1.00000 | |
| 983s 1.00000 | |
| 982s 1.00000 | |
| 976s 1.00000 | |
| 975s 0.85414 0.14586 | |
| 974s 0.23950 0.76050 | |
| 973s 1.00000 | |
| 972s 0.76990 0.23010 | |
| 965s 1.00000 | |
| 964s 1.00000 | |
| 963s 0.87788 0.12212 | |
| 962s 1.00000 | |
| 954s 0.58430 0.41570 | |
| 953s 1.00000 | |
| 952s 1.00000 | |
| 943s 0.33330 0.66670 | |
| 942s 1.00000 | |
| 932s 0.55619 0.44381 | |
| 875s 0.23191 0.76809 | |
| 874s 1.00000 | |
| 873s 1.00000 | |
| 872s 1.00000 | |
| 865s 0.92814 0.07186 | |
| 864s 1.00000 | |
| 863s 0.41006 0.58994 | |
| 862s 1.00000 | |
| 854s 0.35933 0.64067 | |
| 853s 1.00000 | |
| 852s 1.00000 | |
| 843s 0.48403 0.51597 | |
| 842s 0.58716 0.41284 | |
| 832s 1.00000 | |
| 764s 0.62717 0.37283 | |
| 763s 1.00000 | |
| 762s 1.00000 | |
| 754s 0.99539 0.00461 | |
| 753s 1.00000 | |
| 752s 0.39304 0.60696 | |
| 743s 1.00000 | |
| 742s 1.00000 | |
| 732s 1.00000 | |
| 653s 1.00000 | |
| 652s 1.00000 | |
| 643s 1.00000 | |
| 642s 1.00000 | |
| 632s 1.00000 | |
| 542s 1.00000 | |
| 532s 1.00000 | |
| AAKo 1.00000 | |
| AAQo 1.00000 | |
| AAJo 1.00000 | |
| AATo 1.00000 | |
| AA9o 0.45918 0.54082 | |
| AA8o 1.00000 | |
| AA7o 1.00000 | |
| AA6o 1.00000 | |
| AA5o 1.00000 | |
| AA4o 1.00000 | |
| AA3o 1.00000 | |
| AA2o 1.00000 | |
| KKAo 1.00000 | |
| KKQo 1.00000 | |
| KKJo 1.00000 | |
| KKTo 1.00000 | |
| KK9o 1.00000 | |
| KK8o 1.00000 | |
| KK7o 1.00000 | |
| KK6o 1.00000 | |
| KK5o 1.00000 | |
| KK4o 1.00000 | |
| KK3o 1.00000 | |
| KK2o 1.00000 | |
| QQAo 0.26796 0.73204 | |
| QQKo 1.00000 | |
| QQJo 1.00000 | |
| QQTo 1.00000 | |
| QQ9o 0.62606 0.37394 | |
| QQ8o 0.63100 0.36900 | |
| QQ7o 0.83414 0.16586 | |
| QQ6o 0.37108 0.62892 | |
| QQ5o 0.27837 0.72163 | |
| QQ4o 0.61656 0.38344 | |
| QQ3o 0.61491 0.38509 | |
| QQ2o 0.71415 0.28585 | |
| JJAo 1.00000 | |
| JJKo 1.00000 | |
| JJQo 1.00000 | |
| JJTo 1.00000 | |
| JJ9o 0.96829 0.03171 | |
| JJ8o 1.00000 | |
| JJ7o 0.41650 0.58350 | |
| JJ6o 0.63631 0.36369 | |
| JJ5o 0.34680 0.65320 | |
| JJ4o 0.92599 0.07401 | |
| JJ3o 0.74261 0.25739 | |
| JJ2o 0.79661 0.20339 | |
| TTAo 1.00000 | |
| TTKo 1.00000 | |
| TTQo 1.00000 | |
| TTJo 1.00000 | |
| TT9o 0.08427 0.06078 0.85495 | |
| TT8o 0.74101 0.25899 | |
| TT7o 1.00000 | |
| TT6o 0.43522 0.56478 | |
| TT5o 0.82852 0.17148 | |
| TT4o 0.96969 0.03031 | |
| TT3o 0.84868 0.15132 | |
| TT2o 0.68188 0.31812 | |
| 99Ao 0.82172 0.17828 | |
| 99Ko 1.00000 | |
| 99Qo 1.00000 | |
| 99Jo 1.00000 | |
| 99To 1.00000 | |
| 998o 0.72651 0.03358 0.23991 | |
| 997o 0.71591 0.28409 | |
| 996o 0.54140 0.01857 0.44003 | |
| 995o 0.87659 0.12341 | |
| 994o 0.74288 0.25712 | |
| 993o 1.00000 | |
| 992o 0.84429 0.15571 | |
| 88Ao 0.29321 0.70679 | |
| 88Ko 1.00000 | |
| 88Qo 0.58737 0.41263 | |
| 88Jo 0.72571 0.27429 | |
| 88To 0.55372 0.44628 | |
| 889o 0.68614 0.31386 | |
| 887o 1.00000 | |
| 886o 0.89289 0.03829 0.06882 | |
| 885o 0.68620 0.31380 | |
| 884o 0.75018 0.24982 | |
| 883o 0.48848 0.51152 | |
| 882o 0.59760 0.40240 | |
| 77Ao 0.24799 0.75201 | |
| 77Ko 1.00000 | |
| 77Qo 0.54249 0.45751 | |
| 77Jo 1.00000 | |
| 77To 0.92885 0.07115 | |
| 779o 0.90018 0.09982 | |
| 778o 1.00000 | |
| 776o 0.57092 0.42908 | |
| 775o 0.37279 0.62721 | |
| 774o 0.72582 0.27418 | |
| 773o 0.62657 0.37343 | |
| 772o 0.35834 0.64166 | |
| 66Ao 1.00000 | |
| 66Ko 1.00000 | |
| 66Qo 1.00000 | |
| 66Jo 0.46024 0.53976 | |
| 66To 0.79676 0.20324 | |
| 669o 1.00000 | |
| 668o 0.01796 0.98204 | |
| 667o 1.00000 | |
| 665o 0.92203 0.07797 | |
| 664o 0.45659 0.54341 | |
| 663o 0.68987 0.27688 0.03325 | |
| 662o 1.00000 | |
| 55Ao 0.48988 0.51012 | |
| 55Ko 1.00000 | |
| 55Qo 0.36829 0.63171 | |
| 55Jo 1.00000 | |
| 55To 0.86457 0.13543 | |
| 559o 0.68859 0.31141 | |
| 558o 0.07265 0.92735 | |
| 557o 1.00000 | |
| 556o 0.80834 0.05714 0.13452 | |
| 554o 0.83608 0.16392 | |
| 553o 0.54546 0.30064 0.15390 | |
| 552o 1.00000 | |
| 44Ao 1.00000 | |
| 44Ko 1.00000 | |
| 44Qo 1.00000 | |
| 44Jo 0.76000 0.24000 | |
| 44To 0.36637 0.34912 0.28451 | |
| 449o 0.86116 0.13884 | |
| 448o 0.71298 0.28702 | |
| 447o 0.95160 0.04840 | |
| 446o 0.30722 0.69278 | |
| 445o 0.21482 0.39363 0.39155 | |
| 443o 0.44798 0.55202 | |
| 442o 0.63469 0.36531 | |
| 33Ao 0.67254 0.32746 | |
| 33Ko 0.45392 0.54608 | |
| 33Qo 0.73823 0.26177 | |
| 33Jo 0.55889 0.44111 | |
| 33To 0.21432 0.66213 0.03200 0.09155 | |
| 339o 0.09322 0.84799 0.05880 | |
| 338o 0.94623 0.05377 | |
| 337o 0.44707 0.46898 0.08395 | |
| 336o 0.51553 0.48447 | |
| 335o 0.20977 0.13828 0.65195 | |
| 334o 1.00000 | |
| 332o 0.72753 0.27247 | |
| 22Ao 1.00000 | |
| 22Ko 0.41438 0.58562 | |
| 22Qo 1.00000 | |
| 22Jo 1.00000 | |
| 22To 0.75537 0.24463 | |
| 229o 1.00000 | |
| 228o 0.34977 0.39632 0.25392 | |
| 227o 0.49338 0.45169 0.05493 | |
| 226o 0.01303 0.38096 0.60601 | |
| 225o 0.77299 0.20523 0.02178 | |
| 224o 1.00000 | |
| 223o 1.00000 | |
| AKJo 0.73050 0.26950 | |
| AKTo 0.83291 0.16709 | |
| AK9o 0.48386 0.51614 | |
| AK8o 0.61893 0.38107 | |
| AK7o 0.72748 0.27252 | |
| AK6o 0.56741 0.43259 | |
| AK5o 0.75854 0.24146 | |
| AK4o 0.52190 0.47810 | |
| AK3o 0.81739 0.13184 0.05077 | |
| AK2o 0.90695 0.09305 | |
| AQJo 0.92604 0.07396 | |
| AQTo 0.59071 0.40929 | |
| AQ9o 0.35160 0.64840 | |
| AQ8o 0.73773 0.26227 | |
| AQ7o 0.62715 0.37285 | |
| AQ6o 0.75806 0.24194 | |
| AQ5o 0.46765 0.53235 | |
| AQ4o 0.79330 0.19539 0.01131 | |
| AQ3o 0.68621 0.31379 | |
| AQ2o 0.40504 0.59496 | |
| AJTo 0.51124 0.48876 | |
| AJ9o 0.03361 0.65923 0.01224 0.21736 0.07757 | |
| AJ8o 0.65207 0.34793 | |
| AJ7o 0.68837 0.31163 | |
| AJ6o 0.53608 0.27946 0.18446 | |
| AJ5o 0.82507 0.16343 0.01151 | |
| AJ4o 0.65394 0.32683 0.01923 | |
| AJ3o 0.23632 0.49717 0.11648 0.15003 | |
| AJ2o 0.38969 0.44802 0.16230 | |
| AT9o 0.63164 0.06053 0.19396 0.07336 0.04051 | |
| AT8o 0.67663 0.30761 0.01576 | |
| AT7o 0.46573 0.13336 0.40091 | |
| AT6o 0.41845 0.20317 0.11476 0.26362 | |
| AT5o 0.64824 0.28331 0.06845 | |
| AT4o 0.17513 0.59629 0.05026 0.15609 0.02224 | |
| AT3o 0.65089 0.13319 0.21452 0.00140 | |
| AT2o 0.47783 0.14417 0.37800 | |
| A98o 0.23302 0.76698 | |
| A97o 0.61992 0.30310 0.07698 | |
| A96o 0.65542 0.21124 0.13334 | |
| A95o 0.70946 0.23441 0.05613 | |
| A94o 0.54538 0.12083 0.07651 0.18226 0.07502 | |
| A93o 0.27617 0.37533 0.01117 0.02571 0.26346 0.04816 | |
| A92o 0.57136 0.39666 0.03198 | |
| A87o 0.52581 0.13689 0.33730 | |
| A86o 0.72473 0.27527 | |
| A85o 0.67798 0.28433 0.03770 | |
| A84o 0.45958 0.36953 0.01961 0.07987 0.07141 | |
| A83o 0.39366 0.07687 0.06958 0.42475 0.03515 | |
| A82o 0.86605 0.13231 0.00165 | |
| A76o 0.48488 0.51512 | |
| A75o 0.89190 0.08820 0.01990 | |
| A74o 0.21548 0.24365 0.12501 0.32380 0.09205 | |
| A73o 0.70168 0.19454 0.03570 0.06808 | |
| A72o 0.44404 0.52754 0.02842 | |
| A65o 0.39398 0.10224 0.04968 0.32071 0.13338 | |
| A64o 0.81454 0.16505 0.02041 | |
| A63o 0.36904 0.63096 | |
| A62o 0.01752 0.98248 | |
| A54o 0.49585 0.06245 0.44170 | |
| A53o 0.76936 0.15884 0.07180 | |
| A52o 0.35308 0.29675 0.35016 | |
| A43o 0.86996 0.13004 | |
| A42o 0.42809 0.09302 0.47889 | |
| A32o 0.96217 0.03783 | |
| KQTo 1.00000 | |
| KQ9o 0.38602 0.61398 | |
| KQ8o 0.82526 0.17474 | |
| KQ7o 0.71970 0.28030 | |
| KQ6o 0.72589 0.27411 | |
| KQ5o 0.59160 0.40840 | |
| KQ4o 0.82809 0.17191 | |
| KQ3o 0.64174 0.29597 0.06229 | |
| KQ2o 0.42260 0.44563 0.13177 | |
| KJTo 0.07759 0.92241 | |
| KJ9o 0.85705 0.14295 | |
| KJ8o 0.61767 0.10995 0.27238 | |
| KJ7o 0.74531 0.01629 0.23840 | |
| KJ6o 0.50214 0.00764 0.49022 | |
| KJ5o 0.16750 0.56079 0.17727 0.09445 | |
| KJ4o 0.30536 0.46668 0.05190 0.15325 0.02282 | |
| KJ3o 0.43997 0.52570 0.03433 | |
| KJ2o 0.46093 0.01683 0.52224 | |
| KT9o 0.59728 0.14840 0.25432 | |
| KT8o 0.30854 0.52167 0.16978 | |
| KT7o 0.22816 0.35317 0.41867 | |
| KT6o 0.67843 0.00583 0.31575 | |
| KT5o 0.07036 0.89736 0.00047 0.03181 | |
| KT4o 0.57710 0.01759 0.40530 | |
| KT3o 0.29900 0.16186 0.01303 0.52611 | |
| KT2o 0.62000 0.38000 | |
| K98o 0.62518 0.19865 0.17617 | |
| K97o 0.15681 0.33918 0.50401 | |
| K96o 0.44723 0.55277 | |
| K95o 0.02425 0.66084 0.31491 | |
| K94o 0.57171 0.42829 | |
| K93o 0.47230 0.52770 | |
| K92o 0.75669 0.24331 | |
| K87o 0.80327 0.19673 | |
| K86o 0.81966 0.01771 0.16262 | |
| K85o 0.44009 0.19379 0.12529 0.24083 | |
| K84o 0.29561 0.11105 0.03499 0.55835 | |
| K83o 0.70425 0.01063 0.28512 | |
| K82o 0.12391 0.41558 0.01208 0.44843 | |
| K76o 0.95897 0.02816 0.01287 | |
| K75o 0.34359 0.12849 0.52792 | |
| K74o 0.55809 0.13367 0.30824 | |
| K73o 0.34487 0.09050 0.55420 0.01044 | |
| K72o 0.40315 0.54733 0.04951 | |
| K65o 0.74146 0.25854 | |
| K64o 0.37598 0.51213 0.11189 | |
| K63o 0.92641 0.06345 0.01014 | |
| K62o 0.51784 0.48216 | |
| K54o 0.27355 0.46249 0.26397 | |
| K53o 0.06443 0.59682 0.33875 | |
| K52o 0.54026 0.45974 | |
| K43o 0.42013 0.16118 0.08334 0.33535 | |
| K42o 0.64503 0.04679 0.30819 | |
| K32o 0.55294 0.18844 0.11902 0.13960 | |
| QJ9o 0.78077 0.21923 | |
| QJ8o 0.64187 0.35813 | |
| QJ7o 0.74855 0.19673 0.05472 | |
| QJ6o 0.76128 0.23872 | |
| QJ5o 0.24873 0.01268 0.73859 | |
| QJ4o 0.57812 0.42188 | |
| QJ3o 0.84669 0.15331 | |
| QJ2o 0.39713 0.03217 0.57070 | |
| QT9o 0.94746 0.05254 | |
| QT8o 0.68641 0.10614 0.20745 | |
| QT7o 1.00000 | |
| QT6o 0.52444 0.47556 | |
| QT5o 0.13283 0.10537 0.76180 | |
| QT4o 0.88393 0.02094 0.09513 | |
| QT3o 0.39477 0.09608 0.50915 | |
| QT2o 0.63035 0.36965 | |
| Q98o 0.81778 0.12386 0.05836 | |
| Q97o 0.90406 0.09594 | |
| Q96o 0.25043 0.74957 | |
| Q95o 0.52352 0.04056 0.43591 | |
| Q94o 0.67855 0.11831 0.20314 | |
| Q93o 1.00000 | |
| Q92o 1.00000 | |
| Q87o 1.00000 | |
| Q86o 1.00000 | |
| Q85o 1.00000 | |
| Q84o 1.00000 | |
| Q83o 1.00000 | |
| Q82o 0.12951 0.87049 | |
| Q76o 1.00000 | |
| Q75o 1.00000 | |
| Q74o 1.00000 | |
| Q73o 1.00000 | |
| Q72o 1.00000 | |
| Q65o 1.00000 | |
| Q64o 1.00000 | |
| Q63o 0.21824 0.78176 | |
| Q62o 1.00000 | |
| Q54o 1.00000 | |
| Q53o 0.51274 0.48726 | |
| Q52o 0.55494 0.44506 | |
| Q43o 1.00000 | |
| Q42o 0.58442 0.41558 | |
| Q32o 1.00000 | |
| JT8o 0.44988 0.55012 | |
| JT7o 0.89994 0.10006 | |
| JT6o 1.00000 | |
| JT5o 1.00000 | |
| JT4o 0.26429 0.73571 | |
| JT3o 1.00000 | |
| JT2o 0.59758 0.40242 | |
| J98o 0.12500 0.87500 | |
| J97o 1.00000 | |
| J96o 1.00000 | |
| J95o 0.98844 0.01156 | |
| J94o 0.79992 0.20008 | |
| J93o 0.76416 0.23584 | |
| J92o 1.00000 | |
| J87o 1.00000 | |
| J86o 1.00000 | |
| J85o 1.00000 | |
| J84o 1.00000 | |
| J83o 1.00000 | |
| J82o 1.00000 | |
| J76o 0.44526 0.55474 | |
| J75o 0.70521 0.29479 | |
| J74o 1.00000 | |
| J73o 1.00000 | |
| J72o 1.00000 | |
| J65o 0.18275 0.81725 | |
| J64o 1.00000 | |
| J63o 0.99551 0.00449 | |
| J62o 1.00000 | |
| J54o 1.00000 | |
| J53o 1.00000 | |
| J52o 1.00000 | |
| J43o 1.00000 | |
| J42o 1.00000 | |
| J32o 1.00000 | |
| T97o 0.35037 0.64963 | |
| T96o 1.00000 | |
| T95o 0.57662 0.42338 | |
| T94o 1.00000 | |
| T93o 0.90433 0.09567 | |
| T92o 0.52523 0.47477 | |
| T87o 0.18021 0.81979 | |
| T86o 0.54166 0.45834 | |
| T85o 0.72049 0.27951 | |
| T84o 1.00000 | |
| T83o 1.00000 | |
| T82o 1.00000 | |
| T76o 0.66950 0.33050 | |
| T75o 0.60528 0.39472 | |
| T74o 1.00000 | |
| T73o 1.00000 | |
| T72o 1.00000 | |
| T65o 1.00000 | |
| T64o 0.91529 0.08471 | |
| T63o 0.90036 0.09964 | |
| T62o 0.60572 0.39428 | |
| T54o 1.00000 | |
| T53o 1.00000 | |
| T52o 1.00000 | |
| T43o 1.00000 | |
| T42o 1.00000 | |
| T32o 1.00000 | |
| 986o 1.00000 | |
| 985o 1.00000 | |
| 984o 1.00000 | |
| 983o 1.00000 | |
| 982o 1.00000 | |
| 976o 1.00000 | |
| 975o 0.64056 0.35944 | |
| 974o 1.00000 | |
| 973o 1.00000 | |
| 972o 1.00000 | |
| 965o 1.00000 | |
| 964o 0.57862 0.42138 | |
| 963o 0.84225 0.15775 | |
| 962o 0.95695 0.04305 | |
| 954o 0.94279 0.05721 | |
| 953o 1.00000 | |
| 952o 1.00000 | |
| 943o 1.00000 | |
| 942o 1.00000 | |
| 932o 1.00000 | |
| 875o 1.00000 | |
| 874o 1.00000 | |
| 873o 1.00000 | |
| 872o 1.00000 | |
| 865o 0.46383 0.53617 | |
| 864o 0.96793 0.03207 | |
| 863o 0.84348 0.15652 | |
| 862o 1.00000 | |
| 854o 1.00000 | |
| 853o 1.00000 | |
| 852o 1.00000 | |
| 843o 1.00000 | |
| 842o 1.00000 | |
| 832o 1.00000 | |
| 764o 0.67980 0.32020 | |
| 763o 1.00000 | |
| 762o 1.00000 | |
| 754o 1.00000 | |
| 753o 1.00000 | |
| 752o 1.00000 | |
| 743o 1.00000 | |
| 742o 1.00000 | |
| 732o 1.00000 | |
| 653o 0.76076 0.23924 | |
| 652o 0.54852 0.45148 | |
| 643o 1.00000 | |
| 642o 1.00000 | |
| 632o 1.00000 | |
| 542o 1.00000 | |
| 532o 1.00000 | |
| Game value to SB: -0.012590931333943185 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # three-card poker solver | |
| # Deck: AKQJT98765432 in 3 suits | |
| # Hand ranking: | |
| # AKQs - 432s (straight flush) | |
| # AAA - 222 (trips) | |
| # AKQo - 432o (straight) | |
| # AKJs - 532s (flush) | |
| # AAQ - 223 (pair) | |
| # AKJo - 532o (high card) | |
| import ortools.linear_solver.pywraplp as lp | |
| import itertools | |
| from fractions import Fraction | |
| ranks = "AKQJT98765432" | |
| suits = "cdhs" | |
| def hand_classes(): | |
| """Return all hand classes, with a ranking of each: lower = better hand.""" | |
| order = 1 | |
| classes = [] | |
| # straight flushes | |
| for i in range( len( ranks ) - 2 ): | |
| classes.append( ( ranks[i] + ranks[i+1] + ranks[i+2] + "s", order ) ) | |
| order += 1 | |
| # trips | |
| for i in range( len( ranks ) ): | |
| classes.append( ( ranks[i] + ranks[i] + ranks[i] + "o", order ) ) | |
| order += 1 | |
| # unsuited straight | |
| for i in range( len( ranks ) - 2 ): | |
| classes.append( ( ranks[i] + ranks[i+1] + ranks[i+2] + "o", order ) ) | |
| order += 1 | |
| # flush | |
| for i in range( len( ranks ) ): | |
| for j in range( i+1, len( ranks ) ): | |
| for k in range( j+1, len( ranks ) ): | |
| if j == i+1 and k == j+1: | |
| continue | |
| classes.append( ( ranks[i] + ranks[j] + ranks[k] + "s", order ) ) | |
| order += 1 | |
| # pair | |
| for i in range( len( ranks ) ): | |
| for j in range( len( ranks ) ): | |
| if i == j: | |
| continue | |
| classes.append( ( ranks[i] + ranks[i] + ranks[j] + "o", order ) ) | |
| order += 1 | |
| # high card | |
| for i in range( len( ranks ) ): | |
| for j in range( i+1, len( ranks ) ): | |
| for k in range( j+1, len( ranks ) ): | |
| if j == i+1 and k == j+1: | |
| continue | |
| classes.append( ( ranks[i] + ranks[j] + ranks[k] + "o", order ) ) | |
| order += 1 | |
| return classes | |
| def suit_possibilities( hc ): | |
| if hc[-1] == "s": | |
| return [ tuple( s*3 ) for s in suits ] | |
| if hc[0] == hc[1]: | |
| if hc[1] == hc[2]: | |
| return list( itertools.combinations( suits, r=3 ) ) | |
| else: | |
| return [ (a,b,c) | |
| for a,b in itertools.combinations( suits, r=2 ) | |
| for c in suits ] | |
| return [ (a,b,c) | |
| for a,b,c in itertools.product( suits, repeat=3 ) | |
| if a != b or b != c ] | |
| def slower_joint_probability( hc1, hc2 ): | |
| n = 52 * 51 * 50 * 49 * 48 * 47 | |
| deck = [ (r,s) for s in suits for r in ranks ] | |
| count = 0 | |
| hc1_ranks = list( hc1[:3] ) | |
| hc1_ranks.sort() | |
| hc2_ranks = list( hc2[:3] ) | |
| hc2_ranks.sort() | |
| for h in itertools.permutations( deck, r=3 ): | |
| r1 = [ r for r,s in h ] | |
| r1.sort() | |
| if r1 != hc1_ranks: | |
| continue | |
| suited = ( h[0][1] == h[1][1] and h[1][1] == h[2][1] ) | |
| if hc1[-1] == "s" and not suited: | |
| continue | |
| if hc1[-1] == "o" and suited: | |
| continue | |
| remainder = list( deck ) | |
| remainder.remove( h[0] ) | |
| remainder.remove( h[1] ) | |
| remainder.remove( h[2] ) | |
| for g in itertools.permutations( remainder, r=3 ): | |
| r2 = [ r for r,s in g ] | |
| r2.sort() | |
| if r2 != hc2_ranks: | |
| continue | |
| suited = ( g[0][1] == g[1][1] and g[1][1] == g[2][1] ) | |
| if hc2[-1] == "s" and not suited: | |
| continue | |
| if hc2[-1] == "o" and suited: | |
| continue | |
| count += 1 | |
| return Fraction( count, n ) | |
| def choose2( n ): | |
| return n * (n-1) // 2 | |
| def joint_probability( hc1, hc2 ): | |
| # 52C3 * 49C3 possiblities for the deal | |
| n = 407170400 | |
| num_removed = {} | |
| lhs_distinct = len( set( hc1[:3] ) ) | |
| if hc1[-1] == 's': | |
| num_removed[hc1[0]] = 1 | |
| num_removed[hc1[1]] = 1 | |
| num_removed[hc1[2]] = 1 | |
| lhs = 4 | |
| elif lhs_distinct == 3: | |
| num_removed[hc1[0]] = 1 | |
| num_removed[hc1[1]] = 1 | |
| num_removed[hc1[2]] = 1 | |
| # 4*4*4 - 3 | |
| lhs = 60 | |
| elif lhs_distinct == 2: | |
| num_removed[hc1[0]] = 2 | |
| num_removed[hc1[2]] = 1 | |
| # 4C2 * 4 | |
| lhs = 24 | |
| elif lhs_distinct == 1: | |
| num_removed[hc1[0]] = 3 | |
| # 4C3 | |
| lhs = 4 | |
| else: | |
| assert False | |
| def available( rank ): | |
| return max( 4 - num_removed.get( rank, 0 ), 0 ) | |
| def single_suit(): | |
| n_avail = [ available(r) for r in hc2[:3] ] | |
| n_avail.sort() | |
| if n_avail == [4,4,4]: | |
| return 4 | |
| elif n_avail == [3,4,4]: | |
| return 3 | |
| elif n_avail == [2,4,4]: | |
| return 2 | |
| elif n_avail == [1,4,4]: | |
| return 1 | |
| elif n_avail == [2,3,4]: | |
| # Problem case, looks like AAKo AKQs | |
| # The suit of K might match A or it might not | |
| # of the 4C2 ways we made AA, | |
| # 1/2 of the time the K will match | |
| # e.g.: | |
| # cdc h or s | |
| # cdd h or s | |
| # cdh s only | |
| # cds h only | |
| return Fraction( 3, 2 ) | |
| elif n_avail == [3,3,3]: | |
| if hc1[-1] == 's': | |
| # AKQs AKQs | |
| return 3 | |
| else: | |
| # AKQo AKQs | |
| # 4*4*4-4 possiblities | |
| # We can make ABC all different in 4*3*2 ways, 1 suit remaining | |
| # We can make AAB, ABA, BAA in 3*4*3 ways, 2 suits remaining | |
| return Fraction( 24, 60 ) * 1 + Fraction( 36, 60 ) * 2 | |
| elif n_avail == [3,3,4]: | |
| if hc1[-1] == 's': | |
| # AKQs AKJs | |
| return 3 | |
| else: | |
| # AKQo AKJs | |
| # 4*4*4-4 possibilities | |
| # We can make ABC all different in 4*3*2 ways, 2 suits remaining | |
| # We can make AAB in 4*3 ways, 3 suits remaining | |
| # We can make ABA, BAA in 2*4*3 ways, 2 suits remaining | |
| return Fraction( 24, 60 ) *2 + Fraction( 12, 60 ) * 3 + Fraction ( 24, 60 ) * 2 | |
| else: | |
| assert False | |
| rhs_distinct = len( set( hc2[:3] ) ) | |
| if hc2[-1] == 's': | |
| rhs = single_suit() | |
| elif rhs_distinct == 3: | |
| least = min( available(r) for r in hc2[:3] ) | |
| # if one suit missing, then 4*4*3 - 3 | |
| rhs = available(hc2[0]) * available(hc2[1]) * available(hc2[2]) - \ | |
| single_suit() | |
| elif rhs_distinct == 2: | |
| pair_suits = available(hc2[0]) | |
| kicker_suits = available(hc2[2]) | |
| rhs = choose2( pair_suits ) * kicker_suits | |
| elif rhs_distinct == 1: | |
| trip_suits = available(hc2[0]) | |
| if trip_suits < 3: | |
| rhs = 0 | |
| elif trip_suits == 3: | |
| rhs = 1 | |
| elif trip_suits == 4: | |
| rhs = 4 | |
| else: | |
| assert False | |
| # print( hc1, lhs, hc2, rhs ) | |
| return Fraction( lhs * rhs, n ) | |
| def slow_joint_probability( hc1, hc2 ): | |
| # Enumerate all possibilities and count them | |
| ranks = hc1[:3] + hc2[:3] | |
| # 52C3 * 49C3 possiblities for the deal | |
| n = 407170400 | |
| #n = 1 | |
| distinct = len( set( ranks ) ) | |
| if distinct == 6: | |
| if hc1[-1] == "s" and hc2[-1] == "s": | |
| return Fraction(16, n) | |
| elif hc1[-1] == "s": | |
| return Fraction(4 * 60, n) | |
| elif hc2[-1] == "s": | |
| return Fraction(60 * 4, n) | |
| else: | |
| return Fraction(60 * 60, n) | |
| count = 0 | |
| loop_size = 0 | |
| sc1 = suit_possibilities( hc1 ) | |
| sc2 = suit_possibilities( hc2 ) | |
| for s1 in sc1: | |
| for s2 in sc2: | |
| cards = zip( ranks, s1 + s2 ) | |
| loop_size += 1 | |
| if len( set( cards ) ) == 6: | |
| count += 1 | |
| return Fraction( count, n ) | |
| import random | |
| def test_joint_probability(): | |
| test_cases = [ "AKQs", "KQJs", "KT6s", "654s", | |
| "AAAo", "AAKo", "KKAo", "664o", | |
| "AKQo", "KQJo", "KT6o", "654o" ] | |
| for a in test_cases: | |
| for b in test_cases: | |
| p = joint_probability( a, b ) | |
| p2 = slow_joint_probability( a, b ) | |
| p3 = slower_joint_probability( a, b ) | |
| print( a, b, p, p2, p3 ) | |
| assert p == p2 | |
| assert p2 == p3 | |
| def test_joint_probability_fast( short = False): | |
| if short: | |
| test_cases = [ "AKQs", "KQJs", "KT6s", "654s", | |
| "AAAo", "AAKo", "KKAo", "664o", | |
| "AKQo", "KQJo", "KT6o", "654o" ] | |
| else: | |
| test_cases = [ hc for hc,r in hand_classes() ] | |
| for a in test_cases: | |
| for b in test_cases: | |
| p = slow_joint_probability( a, b ) | |
| p2 = joint_probability( a, b ) | |
| print( a, b, p, p2 ) | |
| assert p == p2 | |
| def test_total_probability(): | |
| total = 0 | |
| hc = hand_classes() | |
| for a, _ in hc: | |
| for b, _ in hc: | |
| p = joint_probability( a, b ) | |
| total += p | |
| #print( a, b, p, total ) | |
| print( total ) | |
| assert total == 1 | |
| # 4-bet cap | |
| # P1 has 1 simplex | |
| p1_strategies = [ | |
| "F", | |
| "CF", "CC", "CRF", "CRC", # complete the SB | |
| "RF", "RC", "RR" # raise | |
| ] | |
| # P2 has 2 simplices, depending on the P1 first action. | |
| p2_strategies = [ | |
| "C/K", "C/RF", "C/RC", "C/RR", # P1 calls | |
| "R/F", "R/C", "R/RF", "R/RC" # P1 raises | |
| ] | |
| p2_simplicies = [ p2_strategies[:4], p2_strategies[4:] ] | |
| # P2\P1 F CF CC CRF CRC RF RC RR | |
| # C/K x x x x x | |
| # C/RF x x x x x | |
| # C/RC x x x x x [zeros] | |
| # C/RR x x x x x | |
| # R/F x x x | |
| # R/C x x x | |
| # R/RF [zeros] x x x | |
| # R/RC x x x | |
| def payoff( p1, p2, sb, winner ): | |
| # P1 is the small blind | |
| # P2 is the big blind | |
| # Return the payoff to P1 | |
| if p1[0] == "F": | |
| # Count a small-blind fold in only one simplex. | |
| if p2[0] == "C": | |
| return 0 - sb | |
| else: | |
| return 0 | |
| if p1[0] == "C": | |
| if p2[0] != 'C': | |
| # not applicable | |
| return 0 | |
| if p2[2] == 'K': | |
| # C/K, pot size = 2 | |
| return 2 * winner - 1 | |
| assert p2[2] == 'R' | |
| if p1[1] == 'F': | |
| # C/R/F, pot size = 2 | |
| return -1 | |
| if p1[1] == 'C': | |
| # C/R/C, pot size = 4 | |
| return 4 * winner - 2 | |
| assert p1[1] == 'R' | |
| if p2[3] == 'F': | |
| # C/R/R/F, pot size = 4 | |
| return 2 | |
| if p2[3] == 'C': | |
| # C/R/R/C, pot size = 6 | |
| return 6 * winner - 3 | |
| assert p2[3] == 'R' | |
| if p1[2] == 'F': | |
| # C/R/R/R/F | |
| return -3 | |
| if p1[2] == 'C': | |
| # C/R/R/R/C | |
| return 8 * winner - 4 | |
| assert False | |
| assert p1[0] == "R" | |
| if p2[0] != 'R': | |
| # not applicable | |
| return 0 | |
| if p2[2] == 'F': | |
| # R/F, win the big blind | |
| return 1 | |
| if p2[2] == 'C': | |
| # R/C | |
| return 4 * winner - 2 | |
| assert p2[2] == 'R' | |
| if p1[1] == 'F': | |
| # R/R/F | |
| return -2 | |
| if p1[1] == 'C': | |
| # R/R/C, pot size = 6 | |
| return 6 * winner - 3 | |
| assert p1[1] == 'R' | |
| if p2[3] == 'F': | |
| # R/R/R/F | |
| return 3 | |
| if p2[3] == 'C': | |
| # R/R/R/C | |
| return 8 * winner - 4 | |
| assert False | |
| def show_payoffs(): | |
| print( "P1 payoffs:") | |
| for winner in [0, 0.5, 1]: | |
| if winner == 0: | |
| print( "\nP2 wins at showdown:" ) | |
| elif winner == 0.5: | |
| print( "\nTie:" ) | |
| else: | |
| print( "\nP1 wins at showdown:" ) | |
| print( "P2 \ P1 " + | |
| "".join( "{:>8}".format( p1) for p1 in p1_strategies ) ) | |
| for p2 in p2_strategies: | |
| line = "{:8}".format( p2 ) | |
| for p1 in p1_strategies: | |
| line += "{:8}".format( payoff( p1, p2, 0.5, winner ) ) | |
| print( line ) | |
| def setup_problem( sb_classes, bb_classes ): | |
| solver = lp.Solver( "ThreeCardPoker", lp.Solver.GLOP_LINEAR_PROGRAMMING ) | |
| small_blind = 0.5 | |
| sb_vars = {} | |
| for sb_hand, sb_rank in sb_classes: | |
| d = {} | |
| for sb_strat in p1_strategies: | |
| name = "p_" + sb_hand + "_" + sb_strat | |
| d[sb_strat] = solver.NumVar( 0, 1.0, name ) | |
| # mix of strategies sums to 1.0 | |
| constraint = solver.Constraint( 1.0, 1.0 ) | |
| for v in d.values(): | |
| constraint.SetCoefficient( v, 1.0 ) | |
| sb_vars[sb_hand] = d | |
| objective = solver.Objective() | |
| # Player 2 has one dummy variable per hand | |
| # hand/strategy expected value | |
| # = sum over SB hands and strategies Y of | |
| # p(SB,Y)*p(SB,BB)*SB_payoff(Y,winner) | |
| # BB hand value for H <= (sum of EV of strategies) for H | |
| # That is, BB picks the best (most negative) strategy against SB's mix. | |
| # Then we maximize sum of all BB hand values to get SB's optimal | |
| # | |
| # c_1 sb_1 + c_2 sb_2 + ... + c_n sb_n >= bb_h | |
| # c_1 sb_1 + c_2 sb_2 + ... + c_n sb_n - bb_h >= 0 | |
| bb_vars = {} | |
| for bb_hand, bb_rank in bb_classes: | |
| # Could be bounded by -4 and 4? | |
| bb_vars[bb_hand] = solver.NumVar( -solver.infinity(), | |
| solver.infinity(), | |
| "bb_" + bb_hand ) | |
| objective.SetCoefficient( bb_vars[bb_hand], 1.0 ) | |
| for bb_strat in p2_strategies: | |
| # One constraint per strategy BB could play | |
| constraint = solver.Constraint(0, solver.infinity() ) | |
| constraint.SetCoefficient( bb_vars[bb_hand], -1.0 ) | |
| for sb_hand, sb_rank in sb_classes: | |
| if sb_rank < bb_rank: | |
| winner = 1 | |
| elif sb_rank > bb_rank: | |
| winner = 0 | |
| else: | |
| winner = 0.5 | |
| p_hand_pair = float( joint_probability( sb_hand, bb_hand ) ) | |
| for sb_strat in p1_strategies: | |
| c = ( p_hand_pair * | |
| payoff( sb_strat, bb_strat, small_blind, winner ) ) | |
| constraint.SetCoefficient( sb_vars[sb_hand][sb_strat], c ) | |
| objective.SetMaximization() | |
| return solver, sb_vars, bb_vars | |
| def show_solution( sb_classes, bb_classes ): | |
| solver, sb_vars, bb_vars = setup_problem( sb_classes, bb_classes ) | |
| print( "Starting solver..." ) | |
| print( solver.NumVariables(), "variables") | |
| print( solver.NumConstraints(), "constraints" ) | |
| solver.EnableOutput() | |
| status = solver.Solve() | |
| if status != solver.OPTIMAL: | |
| print( "Couldn't solve, status", status ) | |
| return | |
| header = "hand " | |
| for sb_strat in p1_strategies: | |
| header += "{:>8}".format( sb_strat ) | |
| print( header ) | |
| print( "--------" + " -------" * len( p1_strategies ) ) | |
| for sb_hand, sb_rank in sb_classes: | |
| hand = "{:8}".format( sb_hand ) | |
| for sb_strat in p1_strategies: | |
| var = sb_vars[sb_hand][sb_strat] | |
| p = var.solution_value() | |
| if p > 0.000001: | |
| hand += " {:7.5f}".format( var.solution_value() ) | |
| else: | |
| hand += " " | |
| print( hand ) | |
| print( "\nGame value to SB: ", solver.Objective().Value() ) | |
| if __name__ == "__main__": | |
| hc = hand_classes() | |
| show_solution( hc, hc ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment