JavaRush /Java Blog /Random-JA /初心者向けのJavaゲーム
timurnav
レベル 21

初心者向けのJavaゲーム

Random-JA グループに公開済み
こんにちは、友人、そして将来の同僚です! 初心者向け Java ゲーム - 1つい最近、実際のプロジェクトに参加するためのテストを受けて合格したのですが、たまたま個人的な事情によりRP自体に参加できなくなってしまいました。RP テストのような興味深い問題の後は、特に私がすでにほとんどの問題を解いてしまったので、通常のコースの問題はそれほど魅力的な娯楽ではなくなりました。そこで、学習を続けるために自分の才能を無駄にしないために、マルチプレイヤー Web ゲームを作成することにしました。他のゲームへのリンク:
  1. この記事の続き
  2. 2048年
私にとって三目並べは最も単純なゲームのように思えたので、タスクをいくつかのサブタスクに分割することにしました。
  1. ゲームロジックをテストするためのコンソールアプリケーション
  2. マルチプレイヤー
  3. プレーヤー データベースをコンソール アプリケーションにアタッチする
  4. フロントエンドデザインの作成、ページテンプレートの作成、ゲームインターフェイスの作成
  5. すべてを一緒に入れて
このような順序では叱られる可能性があり、おそらくすべての本格的なプロジェクトはまったく異なる順序で構築されます。私はすぐに答え、これについて「初心者向け」の記事を書きます。これを学ぶことができます :) さて、コンソール アプリケーションの作成を始めましょう。レベル 20 の大きなチャレンジと同じ手順に従います。三目並べゲームには何があるの?!
  1. 分野
  2. 2人のプレーヤーが交代で、1人はクロスを入れ、2人目はゼロを入れます。それは簡単です。
フィールドを標準の 3x3 フィールドにします。このようなフィールドはどのように保存できるのでしょうか? 最初のオプションは 2 次元配列です。この配列にはどのような要素を含める必要がありますか? 答えは、これらの要素をどうするかを考える必要があるということです。これは、勝者を見つけるために表示および比較することです。それらを画面に表示するだけの場合、それらを文字列として保持するのが論理的であり、配列自体とそれをループで画面に表示すると、次のようになります。
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
画面には次のように表示されます。
O O _
_ X O
X X X
ただし、表示に加えて、値の比較もあり、ここではすでにオプションが可能です。文字列を比較したり、特別な列挙クラス ( enum) を作成したりすることもできますが、数値を比較し、画面に表示されるときのみ「X」と「O」に置き換えることを好みます。たとえば、1 - 「X」、2 - 「O」、0 - 「_」とします。では、トリプル X または O の一致についてフィールドをチェックするにはどうすればよいでしょうか?
一番最初のアルゴリズムはフィールド全体をチェックすることです
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
勝ちの組み合わせ:
00-01-02, 10-11-12, 20-21-22, 00-10-20, 01-11-21, 02-12-22, 00-11-22, 20-11-02 — всего 8.
数値を比較してチェックしますが、フィールド全体、8 つの組み合わせすべてを毎回チェックする必要があることがわかります。もちろん、これは大したことではありません。これは 0 から 10 億の範囲のアームストロング数値を検索するものではありません。ここでは計算はほとんどありませんが、フィールド全体をチェックするよりも最適なものが必要です。私が思いついた 2 番目のアイデアは、前の動きでマークされたセルのみをチェックすることで、誰がこの動きをしたかがわかるため、勝者を決定することができます。したがって、8 つの組み合わせすべてではなく、セルに応じて 2、3、または 4 つの組み合わせのみが得られます。図を参照してください。 初心者向け Java ゲーム - 2次に、どの組み合わせを起動する必要があるかを判断する方法を理解する必要があります。ここで、2 次元配列を使用するのはあまり便利ではないことに気づきました。他の選択肢も検討してみることにしました。最初に、フィールドを 9 桁の数字で保持できるというアイデアを思いつきました。たとえば、画面に表示したのと同じフィールドを次のように書くことができます: 220012111、それが何であるかを指で説明します。コードは同じです。1 - "X"、2 - "O"、0 - " "、つまり 220012111 = "OO__XOXXX"、または 3 桁ごとに改行を挿入し、スペースを追加した場合明瞭さ:
О О _
_ Х О
Х Х Х
ここでもまた、保管には便利で、展示用の装置が発明されましたが、比較するには不便です。プログラミングでは0からカウントダウンが始まるので、セルに1から9まで番号を振ってみたら解決策が見つかったので、図のように番号を振ってみ 初心者向け Java ゲーム - 3ました。上の図を見ると、2 つの組み合わせのソリューションには奇数のシリアル番号があり、4 つの組み合わせにはシリアル番号 4 があり、3 つの組み合わせには残りのシリアル番号が付いていることがわかります。そこで私は、競技場を数値の規則的な配列に保つ必要があるという結論に達しました。つまり、数値間の単純な反復、選択されたアルゴリズムに従って比較する機能、画面への単純な出力です。比較アルゴリズム自体については。順番に見ていきましょう。すべてのオプションで行と列のチェックが行われますが、それらのみをチェックします。検索結果が見つからない場合は、セル番号の偶数/奇数をチェックし、奇数の場合はゲームに戻ります。これ以上チェックする意味はありません。偶数の場合は、このセルが上にあるかどうかを確認します。左対角線の場合、この対角線の数字は 4 で割ったときの余りが 0 になります。一致する場合は一致するかどうかを確認し、一致するものが見つからない場合は数字 4 を確認し、一致しない場合はゲームに戻ります。はい、コードをさらに進めて、最後の対角線をチェックした結果を返します。おそらく、準備ができていない人にとって、上記の一連の文字を読んでもこれを理解するのは難しいでしょう。しかし、コード自体に多くの文字が含まれていると言う人もいるかもしれません。その方が簡単かもしれません。これについては喜んで議論します。フィールドを整理しました。今度は、交代でそれぞれ独自の記号 (X または O) を持つ 2 人のユーザーを処理する必要があります。最初の段階では、マルチユーザー機能がありません。最も簡単な方法は、アイコンを 1 つずつ使用することです。X は常に最初の動きをし、O は常に 2 番目の動きをし、その後再び X を行います。それはチェックされます ( true/false )。 trueの場合– 現在のプレイヤーは X、falseの場合 – O であり、各動きの開始時に flag=!flag どういうわけかプレイヤーからシグナルを受信する必要があります。彼らが選んだ細胞。ここでは、忘れられないBufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); プレイヤーがコンソールにセル番号を入力し、Enter キーを押すと動きます。入力された数値に対応するセルの値は、上の段落で説明したチェックボックスの現在の状態に応じて、0 から 1 または 2 に変わります。ここで、セルがすでに入力されているときに誰も X を O に変更できないように、入力を検証することが重要です :) プレーヤーはコンソールに何を入力できますか?
  1. 空行
  2. 文字、句読点、括弧...一言で言えば、数字以外
  3. 数値が正しくありません - 負または配列サイズ外、セルが占有されています。
文字列から数字を取得する標準メソッドは、Integer クラスの静的メソッド parseInt です。指定された文字列から数字を取得できない場合は、例外がスローInteger.parseInt("2");NumberFormatExceptionれます。この例外をインターセプトすることで、最初の 2 点から保護できます。3 番目の点については、入力された値をチェックする別のメソッドを作成しますが、文字列リクエストを検証が実行される別のメソッドに移動し、数値のみを返すのが最も正確です。要約すると、フィールドを作成し、それを表示するメソッドを作成し、「このプレイヤーは 1 時間以内に勝ったかどうか」を確認するメソッドを作成し、入力された数値を検証しました。やるべきことはほとんど残されていません。引き分けを確認します。これは、配列を実行して 0 を探し、ゲーム結果を表示する別のメソッドです。これだけで、コードの準備は完了しました。ゲームは小さく、クラスが 1 つだけであることが判明しました。非常にタフなコピーペースト者は、理解せずにすべてを自分のプロジェクトにコピーして、自分で実行することができます。私自身もそうでした。今はそうしないようにしていますし、誰にも勧めません :) JAVA の学習で皆さん頑張ってください! ps、残りのポイント - マルチプレイヤーとデータベースは後で説明します。私はすでに教材の勉強を始めています:)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GameField {

    static int [] canvas = {0,0,0,
                            0,0,0,
                            0,0,0};

    //012, 345, 678, 036, 147, 258, 048, 246
    public static void main(String[] args){

        boolean b;
        boolean isCurrentX = false;
        do {
            isCurrentX = !isCurrentX;
            drawCanvas();
            System.out.println("mark " + (isCurrentX ? "X" : "O"));
            int n = getNumber();
            canvas[n] = isCurrentX ? 1 : 2;
            b = !isGameOver(n);
            if (isDraw()){
                System.out.println("Draw");
                return;
            }
        } while (b);
        drawCanvas();
        System.out.println();

        System.out.println("The winner is " + (isCurrentX ? "X" : "O") + "!");
    }

    static int getNumber(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            try {
                int n = Integer.parseInt(reader.readLine());
                if (n >= 0 && n < canvas.length && canvas[n]==0){
                    return n;
                }
                System.out.println("Choose free cell and enter its number");
            } catch (NumberFormatException e) {
                System.out.println("Please enter the number");
            } catch (IOException e) {
            }
        }
    }

    static boolean isGameOver(int n){
        // 0 1 2
        // 3 4 5
        // 6 7 8
        //поиск совпадений по горизонтали
        int row = n-n%3; //номер строки - проверяем только её
        if (canvas[row]==canvas[row+1] &&
                canvas[row]==canvas[row+2]) return true;
        //поиск совпадений по вертикали
        int column = n%3; //номер столбца - проверяем только его
        if (canvas[column]==canvas[column+3])
            if (canvas[column]==canvas[column+6]) return true;
        //мы здесь, значит, первый поиск не положительного результата
        //если meaning n находится на одной из граней - возвращаем false
        if (n%2!=0) return false;
        //проверяем принадлежит ли к левой диагонали meaning
        if (n%4==0){
            //проверяем есть ли совпадения на левой диагонали
            if (canvas[0] == canvas[4] &&
                    canvas[0] == canvas[8]) return true;
            if (n!=4) return false;
        }
        return canvas[2] == canvas[4] &&
                canvas[2] == canvas[6];
    }

    static void drawCanvas(){
        System.out.println("     |     |     ");
        for (int i = 0; i < canvas.length; i++) {
            if (i!=0){
                if (i%3==0) {
                    System.out.println();
                    System.out.println("_____|_____|_____");
                    System.out.println("     |     |     ");
                }
                else
                    System.out.print("|");
            }

            if (canvas[i]==0) System.out.print("  " + i + "  ");
            if (canvas[i]==1) System.out.print("  X  ");
            if (canvas[i]==2) System.out.print("  O  ");
        }
        System.out.println();
        System.out.println("     |     |     ");
    }

    public static boolean isDraw() {
        for (int n : canvas) if (n==0) return false;
        return true;
    }
}
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION