欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn))

 更新時間:2022年09月27日 08:25:51   作者:獨(dú)一無二的哈密瓜  
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn)),文中的實(shí)現(xiàn)步驟講解詳細(xì),感興趣的可以嘗試一下

1. 人機(jī)對戰(zhàn)

要增添一個人機(jī)對戰(zhàn)的模塊, 最大的難點(diǎn)就是如何讓人機(jī)知道下在什么位置是最好的, 不僅要具備進(jìn)攻的能力, 還需要具備防守的能力.

這里當(dāng)人機(jī)第一次走的時候, 采用標(biāo)準(zhǔn)開局, 下子在最中間.

當(dāng)玩家走了之后, 人機(jī)就需要去判定下在什么位置合理.

這里采用的是評分表的方法來計(jì)算落子在每一個位置的分?jǐn)?shù), 根據(jù)最高分?jǐn)?shù)來進(jìn)行下子.

1.1 演示

1.2 評分表

分析棋形的幾種情況.

例如, 自己是黑子.

"_" 代表 沒有子, "1" 代表 黑子 , "0" 代表 白子

當(dāng)落子只有一顆子的情況

  • ① _ 1 _
  • ② _ 1 0
  • ③ 0 1 _
  • ④ 0 1 0

當(dāng)落子有兩顆子的情況

  • ① _ 1 1 _
  • ② _ 1 1 0
  • ③ 0 1 1 _
  • ④ 0 1 1 0

當(dāng)落子有三顆子的情況

  • ① _ 1 1 1 _
  • ② _ 1 1 1 0
  • ③ 0 1 1 1 _
  • ④ 0 1 1 1 0

當(dāng)落子有四顆子的情況

  • ① _ 1 1 1 1 _
  • ② _ 1 1 1 1 0
  • ③ 0 1 1 1 1 _
  • ④ 0 1 1 1 1 0

當(dāng)落子有五顆子的情況

  • ① _ 1 1 1 1 1 _
  • ② _ 1 1 1 1 1 0
  • ③ 0 1 1 1 1 1 _
  • ④ 0 1 1 1 1 1 0

這里大概的情況分為這幾種, 分別對這幾種情況進(jìn)行一個分?jǐn)?shù)的設(shè)定, 讓機(jī)器人根據(jù)分?jǐn)?shù)的高低優(yōu)先去處理某種情況.

這里設(shè)計(jì)一種分?jǐn)?shù)表

一子情況

二子情況

三子情況

四子情況

五子情況

1.3 算法思路

使用暴力搜索的方法, 將棋盤中每個空格的子, 當(dāng)下子的時候, 去判定下子之后, 橫向得分情況, 豎向得分情況, 左斜得分情況, 右斜的得分情況.

例如, 下子是黑子.

  • 橫向, 去看左邊有多少個黑子, 多少白子, 去看右邊有多少個黑子, 多少白子. 然后根據(jù)評分表, 算得分?jǐn)?shù).
  • 縱向, 去看上方有多少黑子, 多少白子, 再去下方看有多少個黑子, 多少白子, 然后根據(jù)評分表, 算得分?jǐn)?shù).
  • 左斜, 去左下方看有多少黑子, 多少白子, 再去右上方看有多少黑子, 多少白子, 然后根據(jù)評分表, 算得分?jǐn)?shù).
  • 右斜. 去左上方看有多少黑子,多少白子, 再去右下方看有多少黑子, 多少白子, 然后根據(jù)評分表, 算得分?jǐn)?shù).

將四個方向的得分加起來, 算得分?jǐn)?shù), 進(jìn)行下子.

這里這種算法, 只具備了進(jìn)攻, 不具備防守的能力. 要想人機(jī)下棋具備防守的能力, 還需要讓人機(jī)對玩家落子的分?jǐn)?shù)進(jìn)行評估, 如果玩家落子得分更高, 就需要考慮去防守了.

這里就讓, 對每個位置, 機(jī)器人落子, 和玩家落子, 算得機(jī)器人落子的得分, 和玩家落子的得分, 對分?jǐn)?shù)進(jìn)行相加, 然后再去比較, 當(dāng)前是最大的得分情況, 就去當(dāng)前位置落子.

這里進(jìn)行測試的時候, 發(fā)現(xiàn)出現(xiàn)四子的時候, 會出現(xiàn)不進(jìn)攻 或者不防守的情況. 所以在判定的時候, 如果出現(xiàn)了五子連珠的情況, 首先進(jìn)攻. 如果對方有四子, 自己沒法五子, 首先防守.

1.4 具體代碼

1.4.1 評分表方法

根據(jù)評分表來分配分?jǐn)?shù), my表示我下的棋子, his表示他下的棋子

public int score(int my,int his){
        if(my > 5) return 200000;
        if(my == 5 && his == 0) return 200000;
        if(my == 5 && his == 1) return 200000;
        if(my == 5 && his == 2) return 200000;
        if(my == 4 && his == 1) return 3000;
        if(my == 4 && his == 0) return 50000;
        if(my == 4 && his == 2) return 1000;
        if(my == 3 && his == 0) return 3000;
        if(my == 3 && his == 1) return 1000;
        if(my == 3 && his == 2) return 500;
        if(my == 2 && his == 0) return 500;
        if(my == 2 && his == 1) return 200;
        if(my == 2 && his == 2) return 100;
        if(my == 1 && his == 0) return 100;
        if(my == 1 && his == 1) return 50;
        if(my == 1 && his == 2) return 30;
        return 0;
    }

1.4.2 橫向得分方法

算得橫向自己棋子數(shù), 和他的棋子數(shù)

如果遇到空格就不計(jì)算了, 遇到別人的棋子也不計(jì)算了

public int getXScore(int x,int y, int chess){
        int my = 1;
        int his = 0;
        for(int i = x-1; i >= 0; i--){
            if(chess == board[i][y]){
                my++;
            }else if(board[i][y] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        for(int i = x+1; i<board.length; i++) {
            if(chess == board[i][y]){
                my++;
            }else if(board[i][y] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        return score(my,his);
    }

1.4.3 縱向得分方法

算得縱向自己棋子數(shù), 和他的棋子數(shù)

如果遇到空格就不計(jì)算了, 遇到別人的棋子也不計(jì)算了

    private int getYScore(int x, int y, int chess) {
        int my = 1;
        int his = 0;
        for(int i = y-1; i >= 0; i--){
            if(chess == board[x][i]){
                my++;
            }else if(board[x][i] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        for(int i = y+1; i < board.length; i++){
            if(chess == board[x][i]){
                my++;
            }else if(board[x][i] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        return score(my,his);
    }

1.4.4 左斜得分方法

算得左斜向自己棋子數(shù), 和他的棋子數(shù)

如果遇到空格就不計(jì)算了, 遇到別人的棋子也不計(jì)算了

    private int getSkewScore2(int x, int y, int chess) {
        int my = 1;
        int his = 0;
        for(int i = x+1,j=y-1; i<board.length && j >=0; i++,j--){
            if(chess == board[i][j]){
                my++;
            }else if(board[i][j] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        for(int i = x-1,j=y+1; i>=0 && j<board.length; i--,j++){
            if(chess == board[i][j]){
                my++;
            }else if(board[i][j] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        return score(my,his);
    }

1.4.5 右斜得分方法

算得右斜向自己棋子數(shù), 和他的棋子數(shù)

如果遇到空格就不計(jì)算了, 遇到別人的棋子也不計(jì)算了

 private int getSkewScore1(int x, int y, int chess) {
        int my = 1;
        int his = 0;
        for(int i = x-1,j =y-1; i >=0 && j>=0; i--,j--){
            if(chess == board[i][j]){
                my++;
            }else if(board[i][j] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        for(int i = x+1,j=y+1; j<board.length && i < board.length; i++,j++){
            if(chess == board[i][j]){
                my++;
            }else if(board[i][j] == 0){
                break;
            }else{
                his++;
                break;
            }
        }
        return score(my,his);
    }

1.4.6 落子總得分方法

這里如果自己下的子可以優(yōu)先五子連珠就直接下棋.

如果沒有這種情況, 再去判定是否他可以五子連珠, 如果有直接堵住

其他就計(jì)算總分?jǐn)?shù)

    public int getScore(int x,int y) {
        int numX1 = getXScore(x,y,1);
        int numX2 = getXScore(x,y,2);
        int numY1 = getYScore(x,y,1);
        int numY2 = getYScore(x,y,2);
        int skew1 = getSkewScore1(x,y,1);
        int skew2 = getSkewScore1(x,y,2);
        int skew3 = getSkewScore2(x,y,1);
        int skew4 = getSkewScore2(x,y,2);
        if(numX2 >= 200000 || numY2 >= 200000 || skew2 >= 200000 || skew4 >= 200000) {
            return Integer.MAX_VALUE;
        }
        if(numX1 >= 200000 || numY1 >= 200000 || skew1 >= 200000 || skew3 >= 200000){
            return Integer.MAX_VALUE;
        }
        int xScore = getXScore(x,y,1)+getXScore(x,y,2);
        int yScore = getYScore(x,y,1)+getYScore(x,y,2);
        int skewScore1 = getSkewScore1(x,y,1)+getSkewScore1(x,y,2);
        int skewScore2 = getSkewScore2(x,y,1)+getSkewScore2(x,y,2);
        return xScore + yScore + skewScore1 + skewScore2;
    }

1.4.7 確認(rèn)落子位置的方法

 public int[] concluate() {
        int[] res = new int[2];
        int max = 0;
        for(int i = 0; i < Constant.ROW; i++) {
            for(int j = 0; j < Constant.COL; j++) {
                if(board[i][j] != 0) {
                    continue;
                }
                int num = getScore(i,j);
                if(num == 200000){
                    res[0] = i;
                    res[1] = j;
                    return res;
                }
                if(num > max) {
                    max = num;
                    res[0] = i;
                    res[1] = j;
                }
            }
        }
        return res;
    }

到此這篇關(guān)于Java實(shí)現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn))的文章就介紹到這了,更多相關(guān)Java在線五子棋游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)圖片水平和垂直翻轉(zhuǎn)效果

    java實(shí)現(xiàn)圖片水平和垂直翻轉(zhuǎn)效果

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片水平和垂直翻轉(zhuǎn)效果,圖片旋轉(zhuǎn)的靈活運(yùn)用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • RabbitMQ消息拒絕如何解決

    RabbitMQ消息拒絕如何解決

    這篇文章主要介紹了RabbitMQ消息拒絕如何解決問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java鎖擦除與鎖粗化概念和使用詳解

    Java鎖擦除與鎖粗化概念和使用詳解

    這篇文章主要介紹了Java鎖擦除與鎖粗化概念和使用,鎖擦除的主要判定依據(jù)來源于逃逸分析的數(shù)據(jù)支持,如果判斷在一段代碼中,堆上的所有數(shù)據(jù)都不會逃逸出去從而被其他線程訪問到,那就可以把它們當(dāng)做棧上數(shù)據(jù)對待,認(rèn)為它們是線程私有的,同步加鎖自然就無須進(jìn)行
    2023-02-02
  • 淺析JAVA 循環(huán)結(jié)構(gòu)

    淺析JAVA 循環(huán)結(jié)構(gòu)

    這篇文章主要介紹了JAVA 循環(huán)結(jié)構(gòu)的相關(guān)資料,文中講解的非常細(xì)致,示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 面試題:java中為什么foreach中不允許對元素進(jìn)行add和remove

    面試題:java中為什么foreach中不允許對元素進(jìn)行add和remove

    讀者遇到了一個比較經(jīng)典的面試題,也就是標(biāo)題上說的,為什么 foreach 中不允許對元素進(jìn)行 add 和 remove,本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • 解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請求數(shù)據(jù)丟失問題

    解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請求數(shù)據(jù)丟失問題

    這篇文章主要介紹了解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請求數(shù)據(jù)丟失問題,主要包括無異步線程得情況下feign遠(yuǎn)程調(diào)用,異步情況下丟失上下文問題,需要的朋友可以參考下
    2022-05-05
  • SpringCloud中的Seata基本介紹與安裝教程

    SpringCloud中的Seata基本介紹與安裝教程

    Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡單易用的分布式事務(wù)服務(wù),這篇文章主要介紹了SpringCloud之Seata基本介紹與安裝,需要的朋友可以參考下
    2024-01-01
  • 使用Spring Boot實(shí)現(xiàn)操作數(shù)據(jù)庫的接口的過程

    使用Spring Boot實(shí)現(xiàn)操作數(shù)據(jù)庫的接口的過程

    本文給大家分享使用Spring Boot實(shí)現(xiàn)操作數(shù)據(jù)庫的接口的過程,包括springboot原理解析及實(shí)例代碼詳解,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • java?System類和Arrays類詳解

    java?System類和Arrays類詳解

    這篇文章主要介紹了java?System類和Arrays類詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • Java 8新增的方法參數(shù)反射實(shí)例分析

    Java 8新增的方法參數(shù)反射實(shí)例分析

    這篇文章主要介紹了Java 8新增的方法參數(shù)反射,結(jié)合實(shí)例形式分析了java8新增api方法參數(shù)反射相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07

最新評論