質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

Javascript,リバーシの勝利判定の方法の理論は?

受付中

回答 5

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,085

score 15

お世話様です。ebifurai55です。私はWeb系の仕事に就きたく最近、Javascriptを勉強しています。800ページぐらいあった本を読破したのですが、実際のコードは書いたことがないので、自分なりに目標を定め、とりあえずリバーシを作ろうと思ってネット検索を含め、ソースがないかどうか探しました。そこでたどり着いたのがteratailなのですが、以前ここにリバーシ(オセロ)のサンプルプログラムがあったので、実装してみました。ただ少し残念なのは、黒白、順番の表示は点数の判定などがなかったので、自分で考えようと思いましたが、プログラミング初心者の為、どこから手をつけていいのかわからない、わからないことがわからない、、、という状態になっています。一応自分なりの概念は

・盤面の状態の保存
・チェック
・白黒の数値を表示
・勝利判定
・再スタート

という流れなのかな?と思いますが、いろいろと検索しても変数やパラメーターが違うので、どこを変えればいいのか?という結論になりました。私のメンターの人もゆっくりやっていいよ、と言ってくれますが、概念がわからないと同実装したらわかりません。ちょっと自分でもやってみますが、どうしようもない時にこちらに投稿してもいいでしょうか?
今現在勝利判定の所で何を対象にチェックをしたらいいのか、苦戦しています。できれば解決方法のソースを教えてもらいたいです。が、自分の力でどこまでやれるか頑張ります

以下にこのサイトで参考にしたソースコードを載せます。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-language" content="ja">
    <meta charset="UTF-8">
</head>
<html>
  <body>
    <div id="othello"></div>
    <script type="text/javascript" src="reversi.js"></script>
  </body>
</html>
var STONE_BLACK = 'url("http://i.imgur.com/CLEpdaJ.png")';
var STONE_WHITE = 'url("http://i.imgur.com/VZgXNBM.png")';
var BLACK = 1;
var WHITE = 2;

var turn = BLACK;    // 先手は黒

// 10×10のフィールドを作って、石の色を保持する。
// 0: 石がない, BLACK: 黒石, WHITE: 白石、9: 壁
var field = [
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
];
// -------------------------------------------------------
// 盤面を表示する。
function showBoard() {
    var element = document.getElementById("othello");

    for (var y = 1; y <= 8; y++) {
        for(var x = 1; x <= 8; x++) {
            var f = document.createElement("div");
            f.id = "p" + y + x;
            f.style.border = "1px solid black";
            f.style.cssFloat = "left";
            f.style.height = "60px";
            f.style.width = "60px";
            f.style.background = "lime";
            f.style.cursor = "pointer";
            f.addEventListener("click", clickEvent, false);

            if ((x % 8) == 1) {
                f.style.clear = "both";
            }

            if (field[y][x] !== 0) {
                var image = (field[y][x] == BLACK)? STONE_BLACK :STONE_WHITE;
                f.style.backgroundImage = image;
            }
            element.appendChild(f);
        }
    }
}

function playable(y, x, player) {
    var ans = false;
    var opponent = (player == BLACK) ? WHITE : BLACK;
    var delta_y = [-1, -1, 0, 1, 1, 1, 0, -1];
    var delta_x = [0, 1, 1, 1, 0, -1, -1, -1];

    if (field[y][x] === 0) {
        for (var pos = 0; pos < 8; pos++) {
            var count = 0;
            var n = y + delta_y[pos];
            var m = x + delta_x[pos];

            if (field[n][m] === 9 || field[n][m] === player || field[n][m] === 0) {
                continue;
            }

            while (field[n][m] === opponent) {
                n += delta_y[pos];
                m += delta_x[pos];
                count++;

                if (field[n][m] === player) {
                    ans = true;
                    while (count >= 0) {
                        n -= delta_y[pos];
                        m -= delta_x[pos];
                        var f = document.getElementById("p" + n + m);
                        f.style.backgroundImage = (player == BLACK)? STONE_BLACK : STONE_WHITE;
                        field[n][m] = player;
                        count--;
                    }

                }
            }
        }
    }
    return ans;

}

function showWinner(field) {
    var nt = {};
    nt[BLACK] = 0;
    nt[WHITE] = 0;

    for (var x = 1; x < 8; x++)
      for (var y = 1; y < 8; y++)
        nt[field[[x, y]]]++;

    console.log((nt[BLACK] == nt[WHITE])
      ? 'The game ends in a draw.'
      : 'The winner is ' + (nt[WHITE] < nt[BLACK] ? BLACK : WHITE) + '.'
    );
}

function clickEvent() {
    var element = document.getElementById(this.id);
    var y = parseInt(element.id.substr(-2, 1));
    var x = parseInt(element.id.substr(-1, 1));

    var check = playable(y, x, turn);
        if (check) {
            turn = (turn == BLACK)? WHITE : BLACK;
            if ( turn == BLACK) {
                console.log('黒の番です');
            } else {
                console.log('白の番です');
            }
        }
    var win = showWinner(field);

}

onload = function() {
    // 黒と白の初期配置
    field[4][5] = BLACK;
    field[5][4] = BLACK;
    field[4][4] = WHITE;
    field[5][5] = WHITE;
    showBoard();
};

//オセロ実践写経

showWinnerはどこからか引っ張ってきたメソッドです。普通に動きません。なにかご助言いただけないでしょうか?たくさんの方からの投稿まっています。

情報追記
やりたい事
・黒と白の数を表示
・64マスに達したら黒か白かどちらが勝ったか判定をする

現状の問題
・nt[board[[x,y]]]++;
で nt[BLACK]とnt[WHITE]の値が更新されてない。
そのため、ずっと”引き分けの"の表示になる。
・nt[BLACK]とnt[WHITE]をカウントしたいが、どの様に表現しないといけないのか分からない。

将来の実装
64マスに達したらというのではあれば
if ( any === 64 )とかで判定して処理を書きたい

09/29
あれから試したものの、nt[BLACK]とnt[white]の動きがどうしてもわからなかったので、以下の様な実装をしてみました

    // 左端からすべてのマスの確認を行う
    var white_cnt = 0
    var black_cnt = 0
    for (var x = 0; x < 8; x++) {
        for (var y = 0; y < 8; y++) {
            // 空白マスのみおけるのでチェック
            // それ以外は石の数を加算
            switch( field[x][y] ) {
                //case 0:
                //console.log('何もしない');
                //break;
            case 1:
                black_cnt++;
                console.log('黒を1加算');
                console.log('黒の数' + black_cnt);

                break;
            case 2:
                white_cnt++;
                console.log('白を1加算');
                console.log('白の数' + white_cnt);
                break;       
            }
        }
    }

}


これで正常に動いた!と思ったのですが、譜面が進むと、白か黒か枚数が同一ではなくなります。どうすればいいのか思案してましたが、当方playable関数に関してまったく理解がないので、どうも自分流で作れれば作った方がいいのではないかと思いました。トレーニングしてないのに野球の実践で活躍できるかと言うと、リトルリーグと大リーグぐらい違うものだと認識しました。たかだか100行くらいですけど、明日までに解決策が出なかったら、メンターに失敗だったと報告します。

他に何かご助言ありますでしょうか?人格攻撃とか向いてないとか言うのはご遠慮ください。

追記。Switchの0も何を指してるかわかりません

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Lhankor_Mhy

    2020/09/29 13:18

    09/29の質問変更拝読。

    「白か黒か枚数が同一ではなくなります」とは具体的には何が起きていますか?

    キャンセル

  • ebifurai55

    2020/09/29 13:30

    >Lhankor_Mhyさん。

    白とか黒は最初は盤に置いてある数はあってるのですが、枚数が増えてくると同一ではないです。黒が39枚で実際は23枚とか、白も置いた数よりもカウントの数値が合ってない事があります。

    元のcase 0:にはコードが書いてあったのですが、消しました。
    これでわかるでしょうか?正直、多少知識があるもののいきなりリバーシでは荷が重すぎでした。10日間で作れとメンターに言われたのですが、達成できませんでした。

    無理なこともあるんだという事も学びました。完成品のコピーを外観だけ変える事もできますが、もともとのこのソースコードもどっかから引っ張ってきたものなので、完全にオリジナルではありません。お金払うっていうか、お金払った方が疑問点も解消できるし、ここで書いてさらし者にはされたくないです。

    キャンセル

  • Lhankor_Mhy

    2020/09/29 16:00

    なんというか、プログラミング以前に、まず質問の仕方を学ぶべきではないかと思いました。

    https://qiita.com/seki_uk/items/4001423b3cd3db0dada7

    もし、この質問が「質問ではなくて雑談をしたかっただけ」ということであれば、失礼いたしました。

    キャンセル

回答 5

+6

普通に動きません。なにかご助言いただけないでしょうか?

「動かない」という言葉だけでは、情報がありません

以下のような条件を揃えてはじめて、何が問題なのか議論できる状態になります。

  • どのような状況で、どのような操作を行ったのか
  • 起きるべき結果
  • 実際の動作状況
  • エラーメッセージ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/27 23:34

    > とりあえず、どこが~という話しをすると

    それすら書かずに概念的な話を先に進めても仕方ない、ということが、言いたかったことです(これも、「確認した事実」と「自分の推測」を分けて書いていただけると、より第三者から理解がしやすくなります)。

    キャンセル

  • 2020/09/27 23:36

    > 今は色々と踏襲しないといけないので

    何かコードを書く上で前提条件があるのでしたら、それも明記してください。提案されたコードが、「条件に当てはまらず採用できない」では誰の得にもなりません。

    キャンセル

  • 2020/09/27 23:38

    > プロユースで言われても何の解決にもなりません。

    デバッグ技術は、プロだろうがアマだろうが、プログラムを完成させたいと願うならば等しく必要とするものです。

    キャンセル

+2

今現在勝利判定の所で何を対象にチェックをしたらいいのか、苦戦しています。
...略
showWinnerはどこからか引っ張ってきたメソッドです。普通に動きません。

showWinnerのロジック自体は動作するかと思います。
全コード中から必要な部分だけ抜き出していますが、下記を実行してみてください。

var BLACK = 1;
var WHITE = 2;
var field = [
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
];

// 以下showWinnerより抜粋

var nt = {};
nt[BLACK] = 0;
nt[WHITE] = 0;

for (var x = 1; x < 8; x++)
  for (var y = 1; y < 8; y++)
    nt[field[[x, y]]]++;

console.log((nt[BLACK] == nt[WHITE])
  ? 'The game ends in a draw.'
  : 'The winner is ' + (nt[WHITE] < nt[BLACK] ? BLACK : WHITE) + '.'
);

// 表示結果
// -> The game ends in a draw.

画面上には表示されず、コンソールに表示があるかと思います。
行っていることはシンプルで、盤面状の1:黒2:白の数をカウントしてどちらが多いかを比較しているだけです。

仮にshowWinnerがうまく動かないのだとすれば引数のfieldがどこかのタイミングで意図せず書き換わっていると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/26 22:31

    解説ありがとうございます。フィールドの数値をConsole.lgoで出してみましたので、挙動がどうなってるか、ヒントでも良いので教えてもらえませんか?

    https://imgur.com/gallery/OdKDZIn

    正直、コマを置いた時に黒と白をそれぞれカウントしないかぎり無理な気がしてきました。どちらにせよ、あと2日間でその処理が達成しないと、失敗です。

    キャンセル

+2

う~ん。ここに書くのをずっとためらっていました。
質問者様みたいなタイプの方も結構このサイト利用されていて、同じような事になっています。
その為みなさん回答したくないんですよ...。

まず基本的なお話

  • プログラム言語の理解とロジックの理解は別物

慌てる気持ち判ります。早く習得したいですよね?
でも「プログラム言語の理解」と「ロジックの理解」は別なんです。
例えるなら英問で書かれた数式とけますか?という事です
この場合「英問」が「プログラム言語」で「ロジック」が「数式」に当てはまります。

ただ「動かない」と言われても「プログラム言語の翻訳」でつまづいているのか?
「数式の解き方」でつまづいているのか?が判りません。
まずどっちで判らないのかはっきりしましょう。

  • プログラム言語の理解はきちんと人の指摘を受けて直し動作させて自分で確認する

一応教育担当者も経験あるのでその時の良くあるパターンで
「辞書片手にやれば問題ないだろう」
と思っている場合です。
普通の言葉と違って1文字1単語位置や誤りがあると動かないのがプログラムです。
せっかく人に指摘されたら確認修正してまずは動かしましょう。
「言われた通りにしたのに治らなかった」ならまた修正方法、症状を伝えれば必ず教えてくれます。
また修正により一部が動くようになっても別が動かない場合もあります。
とにかく指摘事項は一度試してうまくいってもいかなくても報告しましょう。
なれてくれば質問の回数も減るし質問内容も適切になってきます。

  • ロジックの理解はセンスが必要

質問者様を責めているわけではありません。
「ロジックの理解」にはどうしても「センス」が必要なのです。
今回リバーシを課題に選択されたようですがこれがそもそも間違いで
なれている人でも書くのに結構手間がかかったりします。
そこに対戦者がPCとかなったら苦戦します。
(将棋AIでさえ最近話題になるぐらいですから)

ここでいう「ロジック」とはどれだけ処理を分解できるか?の事です。
例として針の時計を思い浮かべて下さい。
プログラマはここまで動作を分解します。

  1. 針の中心位置はどこか?
  2. 長針、短針、秒針の位置はどこか?
  3. 1秒過ぎたか?
  4. 秒針の位置は1秒過ぎたらどこが適切か?
  5. 短針の位置は1秒過ぎたらどこが適切か?
  6. 長針の位置は1秒過ぎたらどこが適切か?
  7. 新しい針の位置にする為に時計を針の無い状態で描写
  8. 針の中心位置から長針の位置までの角度を計算
  9. 計算結果に合わせ長針を描写
  10. 針の中心位置から短針の位置までの角度を計算
  11. 計算結果に合わせ短針を描写
  12. 針の中心位置から秒針の位置までの角度を計算
  13. 計算結果に合わせ秒針を描写

時計の針を1秒動かすだけでも13工程の事を最低限考えます。
この作業を正確にかつ最適に分割する事を行わなければならない為
「センス」が必要となります。

追記。Switchの0も何を指してるかわかりません

この辺りもセンスがある人が見ればすぐに判るのですが 

var field = [
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 0, 0, 0, 0, 0, 0, 0, 0, 9],
    [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
];


これせっかくリバーシの画面を再現していますよね?
そうしたら0はまだ置かれていない場所と判りますよね?
この辺りを気づくかどうかも「センス」なんです。
「センス」は磨くことができます。
ただ人の意見を紳士に受け止めて確認しなければすぐに曇ります。

今回のお題リバーシについて
リバーシはじつは処理がめんどくさいです。
大きく分けて以下の処理が必要です

  1. リバーシ画面を表示する

  2. はじめ中心2x2に白黒のコマを設定

  3. リバーシ画面を更新する

  4. 初期の状態で先手(例として白)が「白のコマ」を置ける位置を算出しておく

  5. 「白のコマ」が置ける位置に置かれたか確認

  6. 置かれた「白のコマ」から8方向に対して「黒のコマ」が続いて
    最後「白のコマ」で終わるか確認

  7. その様な方向が見つかった場合「黒のコマ」を「白のコマ」に変える

  8. 「白のコマ」に変えたらリバーシ画面を更新する

  9. 後手(黒)の番なので「黒のコマ」を置ける位置を算出しておく

  10. 「黒のコマ」が置ける位置に置かれたか確認

  11. 置かれた「黒のコマ」から8方向に対して「白のコマ」が続いて
    最後「黒のコマ」で終わるか確認

  12. その様な方向が見つかった場合「白のコマ」を「黒のコマ」に変える

  13. 「黒のコマ」に変えたらリバーシ画面を更新する

以下繰り返し

最後は先手で「白のコマ」が置ける位置がなくなり
後手で「黒のコマ」が置ける位置がなくなるかで終了を判定
(面全体にコマが配置されなくても終了する場合がある)

以上の処理が適格にできていれば「人対人」のリバーシを作る事ができます。

以上が私からの回答とさせていただきます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/25 20:44

    あれから、ずっと考えてました。僕のプログラムの中で足りないのは、

    「4方向で石を置けるか?」
    という手順でしょうか?

    この場合、4方向で石を反転する処理に仕えないかと思いましたが、容量が悪く。またソースも借りてきたものなので理解が乏しいです。

    この4方向で調べる手順ができればリバーシの判定に役に立つのでしょうか?その場合、ループの処理から外れてグローバル関数で新たに独自関数をするべきでしょうか?

    自分は数学超苦手でした。

    ヒントだけでも教えて下さい。

    キャンセル

+1

リバーシの勝利判定の方法の理論は

ゲームのルールを考えます。以下のいずれかの条件で勝敗が決します。

  1. 盤面が石(色に関係なく)で埋め尽くされたとき
  2. 盤面に石を置く場所はあるが、次の手を打つプレイヤーが置けなくなったとき

クリックイベントのリスナである clickEvent() 関数内で playable() 関数を用いて「継続の可否」を判別しているが、それを無視して勝敗判定showWinner())しています。


模写では、とにかくコードリーディングしてください。

URL叩く(ページをGET要求)
+-HTMLの読み込み
  +-javascriptの読み込み(reversi.js)
      1. 定数や変数の宣言
         STONE_BLACK, STONE_WHITE, BLACK, WHITE, turn, field
      2. 関数の宣言
         showBoard(), playable(y, x, player), showWinner(field), clickEvent()
      3. load イベントで開始(エントリポイント)
         onload = function() { } 


ブラウザ上で発火するイベントを併せて追いかける必要があります。


ちなみに、window.addEventListener("load", listener) を addEventListener("load", listener)と window の省略例は見かけますが、onload = function(){/* omitted */} のような省略は使われません。

別のスクリプトも読む場合、後から読んだスクリプト内に window.onload=function(){} の記述があると上書きされて実行されないためです。極めて限定的な条件で有効な記述と解釈し、showBoard() 内の実装のように addEvewntListener() を使ってください。


追記)

修正欄コメントより
playable関数に関してまったく理解がない

playable では 反転できる石の存在を確認するため、盤上の座標に対して周囲方向をチェックする機能です。
周囲方向の確認のため、field は 10x10 の2次元配列にし、壁 をチェックしたときに配列要素(9)が存在するフォーマットにしていることも読めます(添字番号の範囲は、0-7で実装することもできますが、敢えて0-9 にし、1-8 をそのままゲーム座標に 0, 9 を壁にしている)。

配列と反復処理の関係を理解しているかを試されているのだと感じます。
配列が理解できていないと、分からないところが判ったのは1つの成果ですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/26 22:36

    返信ありがとうございます!ちょっとまだ本を呼んだだけで動けばいっか?なんて思ってるのでご助言ありがとうございます!

    キャンセル

  • 2020/09/27 08:31 編集

    > 動けばいっか?
    動いていますよ。とりあえずの「ゲームが進行する」状態に仕上がっています。
    100行程度のコードですので、「エントリポイント」と回答した箇所から、ゲーム進行がどのようになっているかを読み解くのが近道と思います。
    ----
    以下、厳しい意見になります。「読破」という言葉は、「分かった気になれる魔法の言葉」です。また、「自慢された」と感じる人を増殖する言葉でもあります。

    書籍全般、「同じ書籍を4回通読する頃に初めて筆者の意図も読めて頭の中に残る」と言われますが、技術書に関しては、ページ数こそ多い(入門書ですら普通に300ページ近くある)ものの、1度通読してしまえば、索引から辞書的に使えるのが特徴です。調べながらコードを理解することに徹したほうが良いと思います(追記:専門書の索引は、覚えきれていない用語を覚えるのに適していると感じます)。

    キャンセル

+1

>・nt[board[[x,y]]]++;
>で nt[BLACK]とnt[WHITE]の値が更新されてない。

nt[field[[x, y]]]++の間違いですよね?

さて、field は2次元配列ですので、field[x][y]のようにアクセスする必要があると思います。


>nt[BLACK]とnt[WHITE]をカウントしたいが、どの様に表現しないといけないのか分からない。

nt[BLACK]nt[WHITE]はカウンタとして使われている変数なので、その値自体がカウントなのですが、そういう意味ではなく?

質問の変更に合わせて追記

>白とか黒は最初は盤に置いてある数はあってるのですが、枚数が増えてくると同一ではない

fieldが10*10のところ、0~7までしかループしていないことが原因です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/29 13:48

    追記しました。

    キャンセル

  • 2020/09/29 14:45

    ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る