日記2023/2/25
今日は家でぼっちざろっくを一気見していた。初めてなので一話から見た。演出がぶっ飛んでいるのとネタが豊富なのとで面白かった。
暇だったのでChatGPTで遊んだりもした。具体的にはChatGPTに三目並べ(〇×ゲームともいう)のプログラムを書いてもらった。簡単なプログラムではあるが、10分足らずで完成してしまった。そのときの会話は以下である。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
私:三目並べというゲームをしっていますか
ChatGPT:はい、三目並べというゲームは知っています。三目並べは、2人でプレイする簡単なボードゲームで、3×3の格子状の盤面に交互に○と×を置いていき、先に縦、横、斜めのいずれかの方向に自分のマークを3つ並べた方が勝ちとなるゲームです。勝負がつかない場合は引き分けとなります。非常にシンプルながらも戦略性の高いゲームで、子供から大人まで幅広く楽しまれています。
私:三目並べをJavaで実装したいです。どのようなモジュールに分ければいいですか?
ChatGPT:三目並べをJavaで実装する場合、以下のようなモジュールに分けることができます。
1. Mainモジュール: ゲームの進行、プレイヤーの入力を受け付ける、勝者の判定などのゲームの基本的な処理を行います。
2. Boardモジュール: ゲーム盤の状態を管理し、盤面の初期化、マークの配置、勝者の判定などを行います。
3. Playerモジュール: プレイヤーの情報を管理し、プレイヤーの名前、マーク、手番の管理を行います。
4. Rendererモジュール: ゲーム盤の表示、プレイヤーのターンの表示など、ゲームのビジュアル要素を扱います。
このようにモジュールを分けることで、各モジュールの責務が明確になり、コードの保守性や拡張性が向上するという利点があります。
私:それぞれのモジュールをJavaで書いてもらうことはできますか
ChatGPT:もちろんです!以下に、それぞれのモジュールの基本的な実装例を示します。
Mainモジュール:
javaCopy codepublic class Main {
public static void main(String[] args) {
Board board = new Board();
Player player1 = new Player("Player1", Mark.CROSS);
Player player2 = new Player("Player2", Mark.NOUGHT);
Player currentPlayer = player1;
while (!board.isGameOver()) {
Renderer.renderBoard(board);
Renderer.renderPlayerTurn(currentPlayer);
int[] move = currentPlayer.getMove();
board.placeMark(move[0], move[1], currentPlayer.getMark());
currentPlayer = (currentPlayer == player1) ? player2 : player1;
}
Renderer.renderBoard(board);
Renderer.renderWinner(board.getWinner());
}
}
Boardモジュール:
javaCopy codepublic class Board {
private Mark[][] cells;
public Board() {
cells = new Mark[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cells[i][j] = Mark.EMPTY;
}
}
}
public boolean placeMark(int row, int col, Mark mark) {
if (cells[row][col] != Mark.EMPTY) {
return false;
}
cells[row][col] = mark;
return true;
}
public boolean isGameOver() {
return getWinner() != null || isBoardFull();
}
public boolean isBoardFull() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (cells[i][j] == Mark.EMPTY) {
return false;
}
}
}
return true;
}
public Mark getWinner() {
for (int i = 0; i < 3; i++) {
if (cells[i][0] == cells[i][1] && cells[i][1] == cells[i][2] && cells[i][0] != Mark.EMPTY) {
return cells[i][0];
}
}
for (int j = 0; j < 3; j++) {
if (cells[0][j] == cells[1][j] && cells[1][j] == cells[2][j] && cells[0][j] != Mark.EMPTY) {
return cells[0][j];
}
}
if (cells[0][0] == cells[1][1] && cells[1][1] == cells[2][2] && cells[0][0] != Mark.EMPTY) {
return cells[0][0];
}
if (cells[0][2] == cells[1][1] && cells[1][1] == cells[2][0] && cells[0][2] != Mark.EMPTY) {
return cells[0][2];
}
return null;
}
public Mark getMark(int row, int col) {
return cells[row][col];
}
}
Playerモジュール:
javaCopy codeimport java.util.Scanner;
public class Player {
private String name;
private Mark mark;
public Player(String name, Mark mark) {
this.name = name;
this.mark = mark;
}
public String getName() {
return name;
Playerモジュールの先頭から、Javaで続きを書いてください。
javaCopy code public Mark getMark() {
return mark;
}
public int[] getMove() {
Scanner scanner = new Scanner(System.in);
int row, col;
do {
System.out.print(name + ", enter row (1-3): ");
row = scanner.nextInt() - 1;
System.out.print(name + ", enter column (1-3): ");
col = scanner.nextInt() - 1;
} while (row < 0 || row > 2 || col < 0 || col > 2);
return new int[] {row, col};
}
}
Rendererモジュール:
javaCopy codepublic class Renderer {
public static void renderBoard(Board board) {
System.out.println("-------------");
for (int i = 0; i < 3; i++) {
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(board.getMark(i, j) + " | ");
}
System.out.println();
System.out.println("-------------");
}
}
public static void renderPlayerTurn(Player player) {
System.out.println(player.getName() + "'s turn (" + player.getMark() + ")");
}
public static void renderWinner(Mark winner) {
if (winner == null) {
System.out.println("It's a draw!");
} else {
System.out.println(winner + " wins!");
}
}
}
以上が、三目並べをJavaで実装するために必要なモジュールの実装例になります。各モジュールの責務を明確にし、それぞれの役割に特化したコードを書くことで、保守性や拡張性を向上させることができます。
私:ありがとうございます。Markクラスが見当たらないのですが、Javaで書いてくれますか
ChatGPT:申し訳ありません。以下に Mark クラスの実装例を示します。
javaCopy codepublic enum Mark {
X, O
}
このように Mark クラスは、 X と O の2つの値を持つ enum として実装することが一般的です。 enum は、列挙型を表現するための機能であり、定数の集合体として扱われます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ここで、Markクラスは修正の必要がある。上のコードではXとOの値を持つものとして書かれているが、ほかのコードを見るとCROSS、NOUGHT、EMPTYの値を持つものとして定義される必要があるのだ。こうした小さな不整合はあるものの、修正を含めても殆ど頭も使わずに10分で出来てしまった。うまく質問していけばもっと大きいプログラムも書けそうだ。
ちなみに完成したプログラムを実行するとプロンプトに以下のような表示がされる。マークする位置を行、列の順にひとつづつ入力し、それをプレイヤーが交互に行う仕様になっている。細かい仕様を指定していなくてもいい感じの仕様を決めてくれるのも便利である。
ーーーーーーーーーーーーー
| EMPTY | EMPTY | EMPTY |
ーーーーーーーーーーーーー
| EMPTY | EMPTY | EMPTY |
ーーーーーーーーーーーーー
| EMPTY | EMPTY | EMPTY |
Player1's turn (CROSS)
Player1, enter row (1-3):
夕飯に煮込みハンバーグを作った。作るのはまだ2回目なのだが思いのほか美味しくできた。ソースに椎茸の粉を入れたのが効いたのかもしれない。これから極めていきたい。
体組成計に乗ると、一日中家にいたにもかかわらず少しだけ痩せていた。今日はリングフィットをいつもよりかなり多めにプレイしていたのでその結果がでたのだと思われる。あと鏡を通した見た目でも、お腹周りが痩せたように思える。引き続き頑張りたい。
【今日の体重と体脂肪率 37日目】
初日 今日 差分
体重(kg) 61.8 61.3 -0.5
体脂肪率(%) 23.8 23.7 -0.1
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?