課題 (10:ベーシック)

作業について

今回の課題は以下のパッケージに作成してください。

パッケージの名前
j1.lesson10

作成するクラスの名前は問題ごとに指示があります。下記を参照してください

課題の提出方法については下記を参照してください。

また、別のコンピューター上に移動する際には、下記を参考にプログラムを持ち帰ってください。

問題

1. 参照の共有 (考察課題)

作成するファイルの名前
SharedReference.txt

ファイルの作成方法については下記を参照してください。

下記は参照を利用したプログラムです。

package j1.lesson10;

import javax.swing.JOptionPane;

public class SharedReference {

    public static void main(String[] args) {
        new SharedReference().start();
    }

    void start() {
        String[] messages = new String[2];
        messages[0] = "hello";
        messages[1] = "world";
        String[] copy = messages;
        copy[0] = "こんにちは";
        copy[1] = "世界";
        for (int i = 0; i < messages.length; i++) {
            JOptionPane.showMessageDialog(null,
                "messages[" + i + "]: " + messages[i]);
        }
        for (int i = 0; i < copy.length; i++) {
            JOptionPane.showMessageDialog(null,
                "copy[" + i + "]: " + copy[i]);
        }
    }
}

次の問題に答えて下さい。

  • 下記のプログラムを実行すると何が表示されるでしょうか
  • プログラム中の変数messages, copyの内容を図示してください
  • プログラムを1行だけ書き換えて、次の順番でメッセージが表示されるようにしてください
    1. messages[0]: hello
    2. messages[1]: world
    3. copy[0]: こんにちは
    4. copy[1]: 世界

2. 参照の差し替え(考察課題)

作成するファイルの名前
ReplaceReference.txt

下記は参照を利用したプログラムです。

package j1.lesson10;

import javax.swing.JOptionPane;

public class ReplaceReference {

    public static void main(String[] args) {
        new ReplaceReference().start();
    }

    void start() {
        String[] messages = new String[2];
        messages[0] = "hello";
        messages[1] = "world";
        assign(messages);
        for (int i = 0; i < messages.length; i++) {
            JOptionPane.showMessageDialog(null,
                "messages[" + i + "]: " + messages[i]);
        }
    }

    void assign(String[] array) {
        array = new String[2];
        array[0] = "こんにちは";
        array[1] = "世界";
    }
}

次の問題に答えて下さい。

  • 下記のプログラムを実行すると何が表示されるでしょうか
  • なぜそのように表示されるでしょうか
  • プログラムを1行だけ書き換えて、次の順番でメッセージが表示されるようにしてください
    1. messages[0]: こんにちは
    2. messages[1]: 世界

3. Tic-Tac-Toe ゲーム

作成するクラスの名前
TicTacToe

Tic-Tac-Toeというゲームがあります(日本ローカルでは○×ゲームと呼ばれています)。これは3×3マスの上に、2人が順番に○×のマークを埋めていって、縦横斜めのいずれかに自分のマークがそろえば勝ちです。

このTic-Tac-Toeゲームを作成する前に、書きかけのプログラムについて少し説明します。

  • ゲームの状態はTicTacToeGameクラスのインスタンスで表します
    • playerフィールドは0があなたの手番を表し、1がコンピュータの手番を表します
    • boardフィールドは3×3の二次元配列で、board[x][y]のように表します
      • board[x][y]が-1のとき、(x, y)はまだ何も書かれていないことを表します
      • board[x][y]が0のとき、(x, y)はあなたが○を書きこんだことを表します
      • board[x][y]が1のとき、(x, y)はコンピュータが×を書きこんだことを表します
    • 上記のインスタンスはcreateGameメソッドで作成できます(先行後攻はランダム)
  • 盤面のそれぞれのマスは□○×のいずれかで表します
    • □はまだ何も書かれていないマスです
    • ○はあなたによって書かれたマスです
    • ×はコンピュータによって書かれたマスです
    • boardToStringメソッドで3×3の盤面の状態を文字列に変換できます
  • 上記を踏まえて、次の手順でTic-Tac-Toeゲームのプログラムを完成させてください。

    1. startメソッドをよく読み、inputCell, isGameSet, changePlayer
      メソッドそれぞれの役割とプログラム全体の流れを考えて下さい
    2. changePlayerメソッドの中身を作成してください
      • このメソッドは、「あなた」と「コンピュータ」の手番を切り替えるメソッドです
    3. inputCellByYouメソッドの中身を作成してください
      • このメソッドは、「あなた」が盤面に「○」を置く番です
      • 現在の盤面を表示して、どこに置くかを入力ダイアログで問い合わせるのがよいでしょう
      • すでに○や×が置いてある場所や、3×3の範囲外には置けません
    4. inputCellByComputerメソッドの中身を作成してください
      • このメソッドは、「コンピュータ」が盤面に「×」を置く番です
      • AIを作るのは大変なので、ランダムに×を配置して構いません
      • すでに○や×が置いてある場所や、3×3の範囲外には置けません
    5. isGameSetメソッドの中身を作成してください
      • このメソッドは、盤面に同じマークが並んでいるかどうかを調べるメソッドです
      • 縦、横、斜めのいずれかに0, 1のどちらかが3つ並んでいればtrueを返してください
      • isStraightメソッドをうまく利用してください
    package j1.lesson10;
    
    import javax.swing.JOptionPane;
    
    public class TicTacToe {
    
        public static void main(String[] args) {
            new TicTacToe().start();
        }
    
        void start() {
            java.awt.Font font = new java.awt.Font("MS ゴシック", 0, 15);
            javax.swing.UIManager.put("Label.font", font);
    
            TicTacToeGame game = createGame();
            for (int i = 0; i < 9; i++) {
                inputCell(game);
                if (isGameSet(game.board)) {
                    JOptionPane.showMessageDialog(null,
                        playerToString(game.player) + "の勝ちです");
                    break;
                }
                changePlayer(game);
            }
        }
    
        TicTacToeGame createGame() {
            TicTacToeGame game = new TicTacToeGame();
            game.player = (int) (Math.random() * 2);
            game.board = new int[3][3];
            for (int x = 0; x < 3; x++) {
                for (int y = 0; y < 3; y++) {
                    game.board[x][y] = -1;
                }
            }
            return game;
        }
    
        void changePlayer(TicTacToeGame game) {
    
    
        }
    
        void inputCell(TicTacToeGame game) {
            if (game.player == 0) {
                inputCellByYou(game.board);
            }
            else {
                inputCellByComputer(game.board);
            }
            JOptionPane.showMessageDialog(null,
                playerToString(game.player) + "の手番が終了しました\n" +
                "現在の盤面:\n" +
                boardToString(game.board));
        }
    
        void inputCellByYou(int[][] board) {
    
    
        }
    
        void inputCellByComputer(int[][] board) {
    
    
        }
    
        boolean isGameSet(int[][] board) {
    
    
        }
    
        boolean isStraight(int a, int b, int c) {
            if (a == -1 || b == -1 || c == -1) {
                return false;
            }
            if (a == b && a == c) {
                return true;
            }
            return false;
        }
    
        String boardToString(int[][] board) {
            String string = "";
            for (int y = 0; y < 3; y++) {
                for (int x = 0; x < 3; x++) {
                    string = string + cellToString(board[x][y]);
                }
                string = string + "\n";
            }
            return string;
        }
    
        String playerToString(int player) {
            if (player == 0) {
                return "あなた";
            }
            else {
                return "コンピュータ";
            }
        }
    
        String cellToString(int cell) {
            if (cell == -1) {
                return "□";
            }
            else if (cell == 0) {
                return "○";
            }
            else {
                return "×";
            }
        }
    
        boolean canPut(int[][] board, int x, int y) {
            if (x < 0 || x > 3) {
                return false;
            }
            if (y < 0 || y > 3) {
                return false;
            }
            if (board[x][y] != -1) {
                return false;
            }
            return true;
        }
    }
    
    class TicTacToeGame {
        int player;
        int[][] board;
    }
    

    余力があれば、inputCellByComputerメソッドの中身を書き換えてコンピュータを強化してください。たとえば、「あと1手で×が揃うなら揃える」「あと1手で○が揃うなら阻止する」などは比較的簡単に作れると思います。

    なお、startメソッドの最初の2行の命令は、Windowsで見た目を整えるための設定です。