競馬の3連単・3連複の買い目点数計算のプログラム

この記事は約24分で読めます。

競馬の3連単や3連複を購入する際に、買い目点数とその時の購入した組み合わせを確認できるコードをPythonとブラウザで確認するためにJavaScriptでそれぞれ書きました。
いずれのコードも改良の余地はあると思いますが、とりあえず動いているのでいいかな。

Python

まずはPythonのコード。

print("#########################################")
A = [2,3,6] #1st
B = [3,6,11] #2nd
C = [1,2,3] #3rd

sanrentan = 0 

for i in range(len(A)):
    for j in range(len(B)):
        for k in range(len(C)):
            if A[i] != B[j] and B[j] != C[k] and C[k] != A[i]:
                print(f"{A[i]}-{B[j]}-{C[k]}")
                sanrentan += 1

print(f"三連単点数:{sanrentan}")

print("-----------------------------------------")

sanrenpuku = 0 #Initialization of the number of patterns
n = 0
rentan = []

for i in range(len(A)):
    for j in range(len(B)):
        for k in range(len(C)):
            if A[i] != B[j] and B[j] != C[k] and C[k] != A[i]:
                sorted_numbers = sorted([A[i], B[j], C[k]])
                if sorted_numbers not in rentan:
                    rentan.append(sorted_numbers)

rentan.sort(key=lambda x: (x[0], x[1], x[2]))

for i in range(len(rentan)):
    print(f"{rentan[i][0]}-{rentan[i][1]}-{rentan[i][2]}")

print(f"三連複点数:{len(rentan)}")
print("#########################################")

2~4行目の配列に選択したい馬番を入力します。A,B,Cはそれぞれ1~3着の馬番を指定するので、上の例では、1着に2,3,6番、2着に3,6,11番、3着に1,2,3番を選択していることになります。これを変更して実行するとそれぞれの買い目点数とその組み合わせの一覧が表示されるようになっています。

これの実行結果を以下に示します。

実行結果
#########################################
2-3-1
2-6-1
2-6-3
2-11-1
2-11-3
3-6-1
3-6-2
3-11-1
3-11-2
6-3-1
6-3-2
6-11-1
6-11-2
6-11-3
三連単点数:14
-----------------------------------------
1-2-3
1-2-6
1-2-11
1-3-6
1-3-11
1-6-11
2-3-6
2-3-11
2-6-11
3-6-11
三連複点数:10
#########################################

ブラウザ上で実行したい(HTML, CSS, JavaScript)

いちいちPythonを実行するのも面倒なので、ブラウザで実行できるようにします。
HTML, CSS, JavaScriptのコードは以下の通りです。なお、CSSは記述したもの(style.css)とは別に任意のリセットCSS(reset.css)を使用しています。適当に探してstyle.cssと同じ階層に入れてください。また、階層は

patterns.html
–css(フォルダ)
—-reset.css
—-style.css
–js(フォルダ)
—-main.js

とします。

HTML (patterns.html)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset=utf-8>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/reset.css?01">
    <link rel="stylesheet" href="css/style.css?01">
    <title>競馬買い目計算</title>
</head>
<body>
    <h1>3連単・3連複 組み合わせ</h1>
    <div class="main">
        <table>
            <thead>
                <tr>
                    <th>着順</th>
                    <!-- 1~18の馬番を横並びに表示 -->
                    <th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th> 
                    <th>9</th><th>10</th><th>11</th><th>12</th><th>13</th><th>14</th><th>15</th><th>16</th> 
                    <th>17</th><th>18</th>
                    <th>全通り</th>
                </tr>
            </thead>
            <tbody>
                <tr id="first-place">
                    <td>1着</td>
                    <!-- 各馬番にチェックボックス -->
                    <td><input type="checkbox" value="1"></td>
                    <td><input type="checkbox" value="2"></td>
                    <td><input type="checkbox" value="3"></td>
                    <td><input type="checkbox" value="4"></td>
                    <td><input type="checkbox" value="5"></td>
                    <td><input type="checkbox" value="6"></td>
                    <td><input type="checkbox" value="7"></td>
                    <td><input type="checkbox" value="8"></td>
                    <td><input type="checkbox" value="9"></td>
                    <td><input type="checkbox" value="10"></td>
                    <td><input type="checkbox" value="11"></td>
                    <td><input type="checkbox" value="12"></td>
                    <td><input type="checkbox" value="13"></td>
                    <td><input type="checkbox" value="14"></td>
                    <td><input type="checkbox" value="15"></td>
                    <td><input type="checkbox" value="16"></td>
                    <td><input type="checkbox" value="17"></td>
                    <td><input type="checkbox" value="18"></td>
                    <td><input type="checkbox" onclick="toggleAll(this, 'first-place')"></td>
                </tr>
                <tr id="second-place">
                    <td>2着</td>
                    <td><input type="checkbox" value="1"></td>
                    <td><input type="checkbox" value="2"></td>
                    <td><input type="checkbox" value="3"></td>
                    <td><input type="checkbox" value="4"></td>
                    <td><input type="checkbox" value="5"></td>
                    <td><input type="checkbox" value="6"></td>
                    <td><input type="checkbox" value="7"></td>
                    <td><input type="checkbox" value="8"></td>
                    <td><input type="checkbox" value="9"></td>
                    <td><input type="checkbox" value="10"></td>
                    <td><input type="checkbox" value="11"></td>
                    <td><input type="checkbox" value="12"></td>
                    <td><input type="checkbox" value="13"></td>
                    <td><input type="checkbox" value="14"></td>
                    <td><input type="checkbox" value="15"></td>
                    <td><input type="checkbox" value="16"></td>
                    <td><input type="checkbox" value="17"></td>
                    <td><input type="checkbox" value="18"></td>
                    <td><input type="checkbox" onclick="toggleAll(this, 'second-place')"></td>
                </tr>
                <tr id="third-place">
                    <td>3着</td>
                    <td><input type="checkbox" value="1"></td>
                    <td><input type="checkbox" value="2"></td>
                    <td><input type="checkbox" value="3"></td>
                    <td><input type="checkbox" value="4"></td>
                    <td><input type="checkbox" value="5"></td>
                    <td><input type="checkbox" value="6"></td>
                    <td><input type="checkbox" value="7"></td>
                    <td><input type="checkbox" value="8"></td>
                    <td><input type="checkbox" value="9"></td>
                    <td><input type="checkbox" value="10"></td>
                    <td><input type="checkbox" value="11"></td>
                    <td><input type="checkbox" value="12"></td>
                    <td><input type="checkbox" value="13"></td>
                    <td><input type="checkbox" value="14"></td>
                    <td><input type="checkbox" value="15"></td>
                    <td><input type="checkbox" value="16"></td>
                    <td><input type="checkbox" value="17"></td>
                    <td><input type="checkbox" value="18"></td>
                    <td><input type="checkbox" onclick="toggleAll(this, 'third-place')"></td>
                </tr>
            </tbody>
        </table>
    </div>

    <div class="line">計算結果</div>

    <div class="result">
        <table>
            <tr>
                <td><div id="result_tan"></div></td>
                <td><div id="result_puku"></div></td>
            </tr>
        </table>
    </div>

    <script src="js/main.js"></script>
</body>
</html>

CSS (style.css)

body{
    padding: 20px;
    margin: 0;
    min-height: 105vh;
}
.checkbox-group {
    margin-bottom: 10px;
}
h1{
    font-size: 30px;
    padding: 15px 0;
}
/* checkbox */
input[type="checkbox"] {
    appearance: auto; /* apply the default style of browser */
    width: 16px;
    height: 16px;
} 
input[type="checkbox"]::-ms-check {
    background-color: white;
    border: 1px solid #ccc;
}  
input[type="checkbox"]:checked {
    accent-color: #0078D4;
}

.main table {
    width: 100%;
    border-collapse: collapse;
    text-align: center;
}

.main th, .main td {
    border: 1px solid #ccc;
    padding: 8px;
    text-align: center;
    vertical-align: middle;
}
.main th{
    background-color: aliceblue;
}
td input[type="checkbox"] {
    margin: 2px;
}
.line{
    width: 100%;
    height: 30px;
    margin: 50px auto 20px;
    text-align: center;
    font-size: 20px;
    background-color: aliceblue;
    border-top: 1px solid black;
    border-bottom: 1px solid black;
}
.result table {
    width: 40%;
}

.result table td {
    width: 50%;
    text-align: center;
}
@media screen and (max-width:720px){
    h1{
        font-size: 25px;
        padding: 15px 0;
    }
    .main table{
        display: block;
        overflow-x: scroll;
        white-space: nowrap;
    }
    .result table {
        width: 100%;
    }
    
    .result table td {
        width: 50%;
        text-align: center;
    }
}

JavaScript (main.js)

document.addEventListener("DOMContentLoaded", function () {
    attachEventListeners("first-place");
    attachEventListeners("second-place");
    attachEventListeners("third-place");
});

function attachEventListeners(id) {
    const checkboxes = document.querySelectorAll(`#${id} td input[type='checkbox']`);
    checkboxes.forEach((chk, index) => {
        if (index < 18) {
            chk.addEventListener("change", calculate);
        }
    });
}

function toggleAll(mainCheckbox, id) {
    const checkboxes = document.querySelectorAll(`#${id} td input[type='checkbox']`);
    checkboxes.forEach((chk, index) => {
        if (index < 18) {
            chk.checked = mainCheckbox.checked;
        }
    });
    calculate();
}

function calculate() {
    const first = [...document.querySelectorAll("#first-place td input:checked")].map(chk => parseInt(chk.value)).filter(num => num <= 18);
    const second = [...document.querySelectorAll("#second-place td input:checked")].map(chk => parseInt(chk.value)).filter(num => num <= 18);
    const third = [...document.querySelectorAll("#third-place td input:checked")].map(chk => parseInt(chk.value)).filter(num => num <= 18);

    let sanrentanCount = 0;
    let sanrentanCombinations = [];
    let sanrenpukuCombinations = [];

    first.forEach(A => {
        second.forEach(B => {
            third.forEach(C => {
                if (A !== B && B !== C && C !== A) {
                    sanrentanCount++;
                    sanrentanCombinations.push(`${A}-${B}-${C}`);

                    let sortedCombo = [A, B, C].sort((a, b) => a - b).join("-");
                    if (!sanrenpukuCombinations.includes(sortedCombo)) {
                        sanrenpukuCombinations.push(sortedCombo);
                    }
                }
            });
        });
    });

    document.getElementById("result_puku").innerText = `三連複点数:${sanrenpukuCombinations.length}点\n\n${sanrenpukuCombinations.join("\n")}`;
    document.getElementById("result_tan").innerText = `三連単点数:${sanrentanCount}点\n\n${sanrentanCombinations.join("\n")}`;
}

実際の動作はこちら↓の公開ページから確認できます。

アルゴリズムを改良したり、デザインを改良したりしたら更新します。

Comments

タイトルとURLをコピーしました