suna8’s blog

還暦を過ぎたジジーの気まぐれ日記

やっぱり趣味のプログラミングは楽しい(Part5)

Part4より

 

やはりここまでのプログラミング作業はChatGPTには重荷だったようで、本来の”生成AI”の能力範囲を超えた使い方だとの結論に達しました。分かってはいましたが……

結局、中途半端な出来損ないJavaソースをEclipseに貼り付け、それを自力で直すことにしましたが、内容がほとんどでたらめだったので、その骨組み(メソッド)を利用しただけで、元々のBASICソースを参照しながら大半のコードを書き換える結果となりました。まあ、こういう作業も嫌いじゃなく、若いころを思い出しながら地道にプログラムを作り込んで行きました。ほんと、20歳前後のころは寝ることを惜しんでパソコンの前でしこしことコード(言語はBASIC)を打ち込んでいたのです。

作ったプログラムは専門雑誌に何度か投稿し掲載もされ、自己満足していた自分がいました。(このあたりの話は長くなるのでここでは割愛)

月刊ASCII 1981年1月号に掲載されたプログラム

実を言うとJava言語は3年前に必要にかられて始めたばかりで、当初は「最近の言語はめんどくさいな」などと思いながら触っていたのですが、慣れてくると開発環境(Eclipse)に馴染んできたせいもあって、徐々に苦痛が快感に変化していったのです。

特にゲームソフトを作りこんでいる最中は夢中になって、若いころと同じように時間を忘れて触っている自分がいたりもします。まさか還暦を過ぎた自分が新たな言語にハマるとは思ってもみませんでした。

 

ということで、完成したJava言語にによる『イスカンダルのトーフ屋ゲーム』は下記のようになりました。ここで公開しても意味はないでしょうけど(本来はGitHubなどで公開すべき?)、とりあえずのメモ代わりに貼り付けておきます。(字数は足りるかな?)

 

Part6へつづく

 

/*
 * イスカンダルのトーフ屋ゲーム
 *         original copyright 1978 by N.Tsuda
 *        convert & arrange to Java version by T.Sunahachi 2023
 */

import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

public class TofuGame {

    static int STARTGOLD = 5000;     // 開始時の所持金
    static int GOALGOLD = 30000;     // 目標金額
    static int TOFUBAIKA = 50;     // トーフの売価
    static int TOFUGENKA = 40;     // トーフの原価
    static int SELLMAX = {500, 200, 100};     // 天気ごとの最大売上個数
    static String
TENKIWORDS = {"晴れ", "曇り", "雨"};    // 天気を表す言葉
    
    static int hare;                 // 晴れの確率
    static int kumori;             // 曇りの確率
    static int ame;                 // 雨の確率

    private static Random random = new Random();

    // メインメソッド
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        String input;

        // 開始時の処理
        System.out.println("イスカンダルのトーフ屋ゲーム (Java版)");
        System.out.print("ルール説明しますか?[y/n]:");
        input = scanner.nextLine();
        if (input.equalsIgnoreCase("y")) {
            displayRules();
        }
        
        do {
            // ゲームのメイン処理
            System.out.println("===== ゲームスタート =====");            
            gameMain();
            // 継続確認処理
            System.out.println();
            System.out.print("プレイを続けますか?[y/n]:");
            input = scanner.nextLine();
            System.out.println();
            if (input.equalsIgnoreCase("n")) {
                System.out.print("おつかれさまでした。");
                break;
            }
        } while (true);
    }

    // 説明文の表示処理
    private static void displayRules() {
        System.out.println();
        System.out.println("ここはイスカンダル星。あなたはここでトーフ屋を経営し、");
        System.out.println("地球への帰還費用を作り出さなくてはいけません。");
        System.out.println("でもお向かいには、コンピュータが経営するトーフ屋があります。。。");
        System.out.println();
        System.out.println("トーフの原価は1個" + TOFUGENKA + "円、販売価格は" + TOFUBAIKA + "円です。");
        System.out.println("1日に売れる個数は天候に左右されます。");
        System.out.println("晴れると" + SELLMAX[0] + "個、曇りだと" + SELLMAX[1] + "個、雨のときは" + SELLMAX[2] + "個まで売れます。");
        System.out.println("トーフは日持ちしないので、売れ残った分はすべて廃棄します。");
        System.out.println("所持金" + STARTGOLD + "円から始めて、早く" + GOALGOLD + "円を超えた方が勝ちです。");
        System.out.println();
    }

    // トーフ屋ゲームのメイン処理
    private static void gameMain() {

        int playerMake;                 // プレイヤーの作成個数
        int computerMake;                 // コンピュータの作成個数
        int playerSold;                 // プレイヤーの売上個数
        int computerSold;                 // コンピュータの売上個数
        int playerProfit;                 // プレイヤーの利益
        int computerProfit;             // コンピュータの利益
        
        int playerGold = STARTGOLD;     // プレイヤーの所持金
        int computerGold = STARTGOLD;     // コンピュータの所持金

        do {
            // 所持金の表示処理
            System.out.println();
            System.out.println("あなたの所持金は " + playerGold + "円 です。");
            System.out.println("わたしの所持金は " + computerGold + "円 です。");
            System.out.println();

            // 勝負の判定処理
            if (playerGold >= GOALGOLD || computerGold >= GOALGOLD) {
                if (playerGold >= computerGold) {
                    System.out.println("***** あなたの勝ちです! *****");
                } else {
                    System.out.println("***** コンピュータの勝ちです *****");
                }
                return;
            }

            // 天気予報の表示処理
            tenkiYohou();

            // トーフの作成処理 
            playerMake = inpTofu(playerGold / TOFUGENKA);
            computerMake = compTofu(computerGold / TOFUGENKA, playerMake);

            // 翌日の天気の決定・表示処理
            int tenki = nextTenki();

            // 結果表示処理
            playerSold = soldTofu(tenki, playerMake);
            computerSold = soldTofu(tenki, computerMake);
            System.out.println("あなたは " + playerMake + "個 作り、" + playerSold + "個 売れました。");
            System.out.println("わたしは " + computerMake + "個 作り、" + computerSold + "個 売れました。");
            playerProfit = playerSold * TOFUBAIKA - playerMake * TOFUGENKA;
            computerProfit = computerSold * TOFUBAIKA - computerMake * TOFUGENKA;
            System.out.println();
            System.out.println("あなたの利益は " + playerProfit + "円 です。");
            System.out.println("わたしの利益は " + computerProfit + "円 です。");

            // 所持金の計算
            playerGold += playerProfit;
            computerGold += computerProfit;

        } while (true);
    }

    // 天気予報の表示
    private static void tenkiYohou() {

        System.out.println("***** 天気予報 *****");

        hare = randomNum(100);
        kumori = randomNum(100 - hare);
        ame = 100 - hare - kumori;

        System.out.println("晴の確率は " + hare + " %です。");
        System.out.println("曇の確率は " + kumori + " %です。");
        System.out.println("雨の確率は " + ame + " %です。");
    }

    // 0~指定数までの乱数を発生させる
    private static int randomNum(int max) {
        if (max == 0) return 0;
        return random.nextInt(max);
    }

    // トーフの作成数の入力処理
    private static int inpTofu(int limit) {

        System.out.println();
        System.out.println("現在、あなたが作ることのできるトーフは" + limit + "個までです。");
        Scanner scanner = new Scanner(System.in);
        int num = 0;
        
        do {
            System.out.print("作る個数を入力してください:");
            try {
                num = scanner.nextInt();
            } catch(InputMismatchException e) { 
                System.out.println("数字を正しく入力してください。");
                scanner.nextLine();        
                // ↑ dummy method! (https://qiita.com/Choco_Late/items/5b6a9fdc98b53194a643)
                continue;
            }
            if (num >= 1 && num <= limit) {
                break;
            } else {
                System.out.println("作ることのできる範囲外の個数です。再入力してください。");
            }
        } while (true);

        return num;
    }

    // コンピュータの作成個数
    private static int compTofu(int limit, int player) {

        int num;
        String watashi;
        if (ame >= 40) {
            num = SELLMAX[2];        // 雨を想定
        } else if (kumori < 40 - ame) {
            num = SELLMAX[0];        // 晴れを想定
        } else {
            num = SELLMAX[1];        // 曇りを想定                
        }
        if (num > limit) {
            num = limit;
        }
        if (num == player) {
            watashi = "も";
        } else {
            watashi = "は";
        }
        System.out.println("わたし" + watashi + " " + num + "個 トーフを作りました。");
        return num;
    }

    // 天気の決定&表示処理
    private static int nextTenki() {

        int tenkiVal;

        // 1~100のサイコロを振る
        int dice = random.nextInt(100) + 1;
        if (dice <= hare) {
            tenkiVal = 0;
        } else if (dice <= hare + kumori) {
            tenkiVal = 1;
        } else {
            tenkiVal = 2;
        }

        System.out.println();
        System.out.println("ーーーーーーーー 次の日 ーーーーーーーー");

        // ウェイト処理
        try {
            for (int i = 0; i < 3; i++) {
                System.out.print("・");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println();

        System.out.println("天候は " + TENKIWORDS[tenkiVal] + " です。");
        return tenkiVal;

    }

    // 売上個数の計算
    private static int soldTofu(int tenki, int make) {

        int sold = make;
        if (make > SELLMAX[tenki]) {
            sold = SELLMAX[tenki];
        }
        return sold;

    }
}