Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲

這篇文章主要介紹了Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)是專業(yè)的裕民網(wǎng)站建設(shè)公司,裕民接單;提供網(wǎng)站建設(shè)、成都做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行裕民網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲

Java第一次實(shí)驗(yàn),老師讓做一個(gè)井字棋,電腦隨機(jī)下棋。

然后就想能不能聰明一點(diǎn),可以判斷出走哪一步棋;然后只能做到不會(huì)輸,還是不夠聰明,只能呆板地堵住用戶,smartRobot的第三個(gè)判斷邏輯找不到最佳位置,贏得概率比較小;而且我沒(méi)事干時(shí),想玩玩這個(gè)小游戲找找成就感,但每次都會(huì)贏了機(jī)器人,所以刪刪改改了四五次,最后才成。

可以選擇誰(shuí)先開(kāi)始,但startGame里的代碼更加冗余了。看著就很亂,但沒(méi)想到好的辦法。

smartRobot里的代碼全部重寫了,比原來(lái)更聰明一點(diǎn)了:下在四個(gè)角的位置時(shí),能優(yōu)先選擇最佳位置;然后沒(méi)有最佳位置時(shí),再隨便找一空的(隨便找空四角位置使用for代替了,比原來(lái)更簡(jiǎn)短)。

然后smartRobot的第一個(gè)和第三個(gè)判斷邏輯,也更聰明一點(diǎn)了。原來(lái)判斷機(jī)器人和判斷用戶的邏輯,是放在一個(gè)for循環(huán)里的,但無(wú)法找到最佳位置,現(xiàn)在分開(kāi)了。

機(jī)器人先開(kāi)始時(shí),才能發(fā)揮出來(lái)新添加的機(jī)器人的“小聰明”;但機(jī)器人原來(lái)的能力發(fā)揮不回來(lái),只有用戶先開(kāi)始時(shí)才能發(fā)揮出原來(lái)的能力。所以各有利弊,無(wú)論誰(shuí)先開(kāi)始都能適應(yīng)。如果機(jī)器人先開(kāi)始,并且用戶第一步棋不是下在四角的位置,那么用戶就必輸了。其他的情況一般都是平局了。

想到一個(gè)因?yàn)榭梢赃x擇誰(shuí)先開(kāi)始而導(dǎo)致 startGame 代碼冗余的問(wèn)題的解決方法,就是使用局部?jī)?nèi)部類。內(nèi)部類能訪問(wèn)到方法的局部對(duì)象。

主邏輯 startGame:

1. 用一個(gè)3X3的二維數(shù)組,存儲(chǔ)棋盤;

2. 用戶輸入1~9下棋;

3. 判斷是否合法,不合法則重新輸入;

4. 將1~9轉(zhuǎn)換成二維的坐標(biāo) x = (pos-1)/3, y = (pos-1)%3,再令二維數(shù)組相應(yīng)位置為 'O';

5. 判斷用戶是否勝利,是則退出;再判斷是否平局,是則退出;

6. 機(jī)器人下棋(根據(jù)輸入等級(jí),調(diào)用不同函數(shù));

7. 打印棋盤顯示出用戶和機(jī)器人下的棋子;

8. 判斷機(jī)器人是否勝利,是則退出;再判斷是否平局,是則退出;都不是返回第1步。

isSuccessful 判斷成功的邏輯:

判斷所有行、列、對(duì)角線是否有連成一條線的,用字符相加的和判斷即可

willBeSuccessful判斷是否將要成功:

這里判斷的是是否有行、列有兩個(gè)相同棋子和一個(gè)空白,用字符相加的和判斷。

calculate 計(jì)算行列對(duì)角線:

使用枚舉類,來(lái)判斷是計(jì)算行,還是計(jì)算列,還是計(jì)算左右對(duì)角線;計(jì)算行列時(shí),傳入一個(gè)1~3的數(shù)字表示是哪一行那一列。

smartRobot 的第一個(gè)判斷邏輯:

如果棋子下在箭頭指向的那個(gè)位置,那么一步棋就可勝利。

機(jī)器人先判斷自己是否有這樣一個(gè)位置,有則下在哪個(gè)地方,勝利;

方法是嘗試填入所有空白地方,每填一次,判斷一次 isSuccessful;

如果沒(méi)有,再判斷對(duì)方是否有這樣一個(gè)位置,有則堵住這個(gè)地方。

Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲

smartRobot 的第三個(gè)判斷邏輯:

如果棋子下在箭頭指向的位置,那么再下一步必會(huì)勝利,因?yàn)橄略诹四莻€(gè)地方,第三列、第三行都是兩個(gè)棋子了,無(wú)論對(duì)方堵哪里,都會(huì)失敗。

也是機(jī)器人先判斷自己是否有這樣一個(gè)位置,有則下;

調(diào)用 willBeSuccessful 判斷是否有這樣的位置。

沒(méi)有則再判斷對(duì)方是否有這樣的位置,有則堵住。

Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲

smartRobot 的第零個(gè)和第二個(gè)判斷邏輯:

處理四個(gè)角和中心的位置,如果用戶下在了中心,那么機(jī)器人必須至少有兩個(gè)棋子下在四角位置才能保證不輸。

更改了無(wú)數(shù)次的代碼:

import java.util.Arrays;
import java.util.Scanner;
 
public class Experiment_1 {
  public static void main(String[] args) {
    ThreeChess game = new ThreeChess();
    game.startGame();
 
  }
}
 
class ThreeChess{
  private char[][] chessBoard = new char[3][3];
  private int size = 0; //已經(jīng)下的棋數(shù)
  private final int CAPACITY = 9; //總共可下的棋數(shù)
 
  ThreeChess(){
    for(char[] line : chessBoard){ //初始化棋盤
      Arrays.fill(line, ' ');
    }
  }
 
  //【游戲開(kāi)始】
  public void startGame(){
    System.out.println("┌───┬───┬───┐");
    System.out.println("│ 1 │ 2 │ 3 │");
    System.out.println("├───┼───┼───┤");
    System.out.println("│ 4 │ 5 │ 6 │");
    System.out.println("├───┼───┼───┤");
    System.out.println("│ 7 │ 8 │ 9 │");
    System.out.println("└───┴───┴───┘");
    System.out.println("輸入 1 ~ 9 表示要下棋的位置");
    System.out.println("O是你的棋子,*是電腦的棋子");
    Scanner in = new Scanner(System.in);
 
    System.out.print("選擇誰(shuí)先開(kāi)始:\n\t1.用戶\n\t2.機(jī)器人\nInput: ");
    int whoFirst = in.nextInt();
    System.out.print("選擇機(jī)器人智商:\n\t1. 999+\n\t2. 250\nInput: ");
    int level = in.nextInt();
 
    class Play{ //代碼重用
      //方法返回-1表示退出
      int robotPlay(){
        if(level == 1)
          smartRobot();
        else
          sillyRobot();
 
        printChessBroad();
        if(isSuccessful() == -1) {
          System.out.println("機(jī)器人勝 (/ □ \\)");
          return -1;
        }else if (size == CAPACITY){
          System.out.println("==游戲平局==");
          return -1;
        }
        return 0;
      }
      int userPlay(){
        int pos;
        while(true){
          System.out.print("下棋位置: ");
          pos = in.nextInt();
          if(pos < 1
              || pos > 9
              || chessBoard[(pos - 1) / 3][(pos - 1) % 3] != ' '){
            System.out.println("輸入錯(cuò)誤,重新輸入!");
            continue;
          } else {
            chessBoard[(pos - 1)/3][(pos - 1) % 3] = 'O';
            size++;
            break;
          }
        }
 
        if(isSuccessful() == 1){
          printChessBroad();
          System.out.println("恭喜,你勝了 ╰(*°▽°*)╯");
          return -1;
        } else if(size == CAPACITY){
          printChessBroad();
          System.out.println("==游戲平局==");
          return -1;
        }
        return 0;
      }
    }
 
    Play play = new Play();
    if(whoFirst == 2){
      while(true){
        //1.機(jī)器人下棋
        if(play.robotPlay() == -1)
          return;
 
        //2.用戶下棋
        if(play.userPlay() == -1)
          return;
      }
    } else {
      while(true){
        //1.用戶下棋
        if(play.userPlay() == -1)
          return;
 
        //2.機(jī)器人下棋
        if(play.robotPlay() == -1)
          return;
      }
    }
  }
 
  //【機(jī)器人下棋】
  private void sillyRobot(){ //笨機(jī)器人
    int l, c;
    while(true){
      l = (int)(Math.random() * 3);
      c = (int)(Math.random() * 3);
      if(chessBoard[l][c] == ' '){
        chessBoard[l][c] = '*';
        break;
      }
    }
    size++;
  }
 
  private int corner = 2;
  private void smartRobot(){ //無(wú)法戰(zhàn)勝的機(jī)器人
    if(chessBoard[1][1] == ' '){ //搶占中心位置
      chessBoard[1][1] = '*';
      size++;
      return;
    }
 
    //1.判斷是否可以下一個(gè)棋子就勝利(不能放在一起同時(shí)判斷,否則有可能錯(cuò)誤最佳位置)
    for(int i = 0; i < 3; i++){
      for(int j = 0; j < 3; j++){
        if(chessBoard[i][j] == ' '){ //【1】如果這個(gè)位置沒(méi)有棋子,就嘗試下載這個(gè)地方,看看是否可以勝;
          chessBoard[i][j] = '*';
          if(isSuccessful() == -1){ //【1】如果勝的話,就下在這個(gè)地方了,返回即可;
            size++;
            return ;
          }
          else
            chessBoard[i][j] = ' ';
        }
      }
    }
 
    for(int i = 0; i < 3; i++){
      for(int j = 0; j < 3; j++){
        //【2】邏輯同【1】
        if(chessBoard[i][j] == ' '){
          chessBoard[i][j] = 'O'; //【2】否則嘗試用戶下在這個(gè)位置
          if(isSuccessful() == 1){ //【2】如果用戶下在這個(gè)位置會(huì)勝利,就占領(lǐng)它。
            chessBoard[i][j] = '*';
            size++;
            return ;
          } else
            chessBoard[i][j] = ' ';
        }
      }
    }
 
    //2.如果用戶下在了中間的話,就趕緊占兩個(gè)四角的位置,才能保證不輸。優(yōu)先級(jí)要比第一個(gè)低。用戶沒(méi)下在中間也可搶占。
    if(corner > 0){
      corner--;
      for(int i = 0; i < 3; i++){ //優(yōu)先找四邊中沒(méi)有用戶棋子的地方下
        if(i == 1)
          continue;
        boolean NoBigO = true;
        for(int j = 0; j < 3; j++){
          if(chessBoard[i][j] == 'O')
            NoBigO = false;
        }
        for(int j = 0; j < 3 && NoBigO; j++){
          if(chessBoard[i][j] == ' '){
            chessBoard[i][j] = '*';
            size++;
            return;
          }
        }
      }
 
      for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
          if(j == 1 || i == 1)
            continue;
          if(chessBoard[i][j] == ' '){
            chessBoard[i][j] = '*';
            size++;
            return;
          }
        }
      }
    } //end if
 
    //3.判斷是否可以下一個(gè)棋子,從而再下一步可以勝利(不能放在一起判斷)
    for(int i = 0; i < 3; i++){
      for(int j = 0; j < 3; j++){
        if(chessBoard[i][j] == ' '){
          chessBoard[i][j] = '*';
          if(willBeSuccessful(-1)){
            size++;
            return;
          } else
            chessBoard[i][j] = ' ';
        }
      }
    }
 
    for(int i = 0; i < 3; i++){
      for(int j = 0; j < 3; j++){
        if(chessBoard[i][j] == ' '){
          chessBoard[i][j] = 'O';
          if (willBeSuccessful(1)) {
            chessBoard[i][j] = '*';
            size++;
            return;
          } else
            chessBoard[i][j] = ' ';
        }
      }
    }
 
    sillyRobot();
  }
 
  //【打印棋盤】
  private void printChessBroad(){
    System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); //模擬清屏
    System.out.println("┌───┬───┬───┐");
    System.out.println("│ " + chessBoard[0][0] + " │ " + chessBoard[0][1] + " │ " + chessBoard[0][2] + " │");
    System.out.println("├───┼───┼───┤");
    System.out.println("│ " + chessBoard[1][0] + " │ " + chessBoard[1][1] + " │ " + chessBoard[1][2] + " │");
    System.out.println("├───┼───┼───┤");
    System.out.println("│ " + chessBoard[2][0] + " │ " + chessBoard[2][1] + " │ " + chessBoard[2][2] + " │");
    System.out.println("└───┴───┴───┘");
  }
 
  //【判斷成功邏輯】
  private enum Choice{
    LINE,      //行
    COLUMN,     //列
    RIGHT_DIAGONAL, //右對(duì)角線
    LEFT_DIAGONAL; //左對(duì)角線
  }
  private int calculate(Choice choice, int i){ //計(jì)算行、列、對(duì)角線是否連成一條線
    switch (choice){
      case LINE:
        return chessBoard[i][0] + chessBoard[i][1] + chessBoard[i][2];
      case COLUMN:
        return chessBoard[0][i] + chessBoard[1][i] + chessBoard[2][i];
      case RIGHT_DIAGONAL:
        return chessBoard[0][0] + chessBoard[1][1] + chessBoard[2][2];
      case LEFT_DIAGONAL:
        return chessBoard[0][2] + chessBoard[1][1] + chessBoard[2][0];
    }
    return 0;
  }
  private int isSuccessful(){
    /*
    返回-1系統(tǒng)勝;返回1用戶勝;返回0表示繼續(xù)下棋。
    系統(tǒng)勝:126 == '*' + '*' + '*'
    用戶勝:237 == 'O' + 'O' + 'O'
    */
    for(int i = 0; i < 3; i++){
      if(calculate(Choice.LINE, i) == 237 || calculate(Choice.COLUMN, i) == 237)
        return 1;
      if(calculate(Choice.LINE, i) == 126 || calculate(Choice.COLUMN, i) == 126)
        return -1;
    }
    if(calculate(Choice.LEFT_DIAGONAL, 0) == 237 || calculate(Choice.RIGHT_DIAGONAL, 0) == 237)
      return 1;
    if(calculate(Choice.LEFT_DIAGONAL, 0) == 126 || calculate(Choice.RIGHT_DIAGONAL, 0) == 126)
      return -1;
    return 0; //繼續(xù)下棋
  }
 
  private boolean willBeSuccessful(int who){ //who:-1表示判斷機(jī)器人的,+1表示判斷用戶的。
    //如果行、列、對(duì)角線有2個(gè)相同棋子的個(gè)數(shù),則將會(huì)勝,
    //190 == 2 * 'O' + ' '
    //116 == 2 * '*' + ' '
 
    int n = 0;
    int s = (who == 1) ? 190 : 116; //用戶or機(jī)器人要計(jì)算的值
 
    for(int i = 0; i < 3; i++){
      if(calculate(Choice.LINE, i) == s)
        n++;
      if(calculate(Choice.COLUMN, i) == s)
        n++;
    }
    //因?yàn)橹行囊欢〞?huì)被占的,所以就不用判斷對(duì)角線了
    return n > 1;
  }
}

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

文章題目:Java怎么實(shí)現(xiàn)簡(jiǎn)單井字棋小游戲
文章URL:http://www.muchs.cn/article6/gdgdog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)云服務(wù)器、網(wǎng)站導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)網(wǎng)站排名、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)