成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

AI智能五子棋算法——假如我是計(jì)算機(jī)

CodeSheep / 2918人閱讀

摘要:所有獲勝的數(shù)量和數(shù)量統(tǒng)計(jì)經(jīng)過(guò)通過(guò)棋盤(pán)上所有可能勝利的情況不過(guò)種而已計(jì)算最合適的落棋目標(biāo)如果我是計(jì)算機(jī),接下來(lái)我要做的就是當(dāng)聰明的人類下好棋之后,我怎樣下好自己的棋。

1.前言

記得讀大學(xué)時(shí),有段時(shí)間特別喜歡和室友們下五子棋,由于腦子不是特別靈光,再加上室友確實(shí)經(jīng)驗(yàn)豐富,自己自然是屢屢戰(zhàn)敗。時(shí)光荏苒,一眨眼好多年過(guò)去了,很是懷念那時(shí)愜意的時(shí)光!大學(xué)畢業(yè)后,室友們都從事了不同行業(yè)的工作,我也是如愿選擇了做“程序員”。AI近些年來(lái)一直很火熱,其他行業(yè)的小伙伴總是誤認(rèn)為我們很厲害的樣子,殊不知“如魚(yú)飲水,冷暖自知”。不過(guò)“專業(yè)思想”還確實(shí)是有的,所以有感寫(xiě)了這篇博文,和大家就五子棋探討一下“計(jì)算機(jī)”思維和“人類”思維的區(qū)別和聯(lián)系。話不多說(shuō),先上一張“戰(zhàn)敗”效果圖(我承認(rèn)我還是下不過(guò)自己的智能算法):點(diǎn)擊查看源代碼:

2.前期工作 2.1畫(huà)棋盤(pán)

五子棋的棋盤(pán)很簡(jiǎn)單,不過(guò)是一些橫豎交叉的線條而已。懂canvas的同學(xué)自然知道是怎么回事:設(shè)計(jì)好坐標(biāo)之后,在畫(huà)布上畫(huà)15條橫豎交叉的線就可以了,也是橫x,豎y,兩個(gè)for循環(huán)而已。上代碼:

context.strokeStyle = "#BFBFBF";   //設(shè)置線條顏色
function drawChessBoard() {  //繪制棋盤(pán)
    for(var i=0; i<15; i++) {
        //橫線條
        context.moveTo(20 + i*40, 20);
        context.lineTo(20 + i*40, 580);
        context.stroke();
        //豎線條
        context.moveTo(20, 20 + i*40);
        context.lineTo(580, 20 + i*40);
        context.stroke();
    }
}
2.2畫(huà)黑白棋子

“棋子”是圓的,有黑、白兩種顏色。只要我們找好圓心點(diǎn),設(shè)置好半徑,顏色就可以了。為了使棋子看起來(lái)更加逼真,可以給棋子中心添加漸變光澤,也不過(guò)是調(diào)用一個(gè)函數(shù),封裝成函數(shù)代碼如下:

function drawChessMan(i, j) {      //繪制棋子
    context.beginPath();
    context.arc(20 + i*40, 20 + j*40, 18, 0, 2*Math.PI);
    context.closePath();
    var gradient = context.createRadialGradient(23 + i*40, 17 + j*40, 18, 23 + i*40, 17 + j*40, 0);
    if(curColor === "white") {
        gradient.addColorStop(0, "#D1D1D1");
        gradient.addColorStop(1, "#F9F9F9");
    }
    if(curColor === "black") {
        gradient.addColorStop(0, "#0A0A0A");
        gradient.addColorStop(1, "#636766");
    }
    context.fillStyle = gradient;
    context.fill();
    curColor = (curColor === "white") ? "black" : "white";
}
2.3 鼠標(biāo)點(diǎn)擊交替畫(huà)黑白棋子

增加鼠標(biāo)點(diǎn)擊事件,在棋盤(pán)上尋找最近的落子點(diǎn)繪制棋子。設(shè)置一個(gè)當(dāng)前棋子顏色變量,黑白交替繪制,實(shí)現(xiàn)這個(gè)功能在棋子繪制函數(shù)中就已經(jīng)存在:curColor = (curColor === "white") ? "black" : "white";下邊是鼠標(biāo)事件監(jiān)聽(tīng)函數(shù)

//鼠標(biāo)落下,畫(huà)棋子
chessboard.onclick = function(e) {
    ......
    var x = e.offsetX;
    var y = e.offsetY;
    var i = Math.floor(x / 40);
    var j = Math.floor(y / 40);
    if(chessManStatus[i][j] === 0) {
        drawChessMan(i, j);
        ......
    }
}
3.核心算法——計(jì)算機(jī)是怎樣思考的? 3.1 計(jì)算所有可能會(huì)贏的數(shù)據(jù)

我們不得不承認(rèn)“計(jì)算機(jī)”的計(jì)算速度比人類要快的多,它能夠每秒進(jìn)行億萬(wàn)次計(jì)算,而且按照既定的流程走,它永遠(yuǎn)不會(huì)累,也不會(huì)失誤。如果我是“計(jì)算機(jī)”,我就把所有對(duì)手可能會(huì)贏的情況全都算出來(lái),然后根據(jù)下棋的過(guò)程,根據(jù)每一次的數(shù)據(jù)情況,計(jì)算出一個(gè)坐標(biāo),這個(gè)坐標(biāo)棋子能夠阻止對(duì)手贏比賽,也能讓自己更快的贏比賽。事實(shí)上,計(jì)算機(jī)也是這樣做的,提前計(jì)算好所有可能會(huì)贏的情況對(duì)聰明的人類來(lái)說(shuō)只需要幾秒,但是對(duì)于計(jì)算機(jī)來(lái)說(shuō),做完這件事情并存儲(chǔ)所有的數(shù)據(jù),只是毫秒間的工作而已。下面是程序的實(shí)現(xiàn)(和我們想象的一樣:將橫的、豎的、傾斜的連著五個(gè)相同棋子的情況都考慮進(jìn)去,就是所有會(huì)贏的情況。而且計(jì)算機(jī)還將棋子的狀態(tài),自己和人的數(shù)據(jù)做分類處理。)

var wins = [], personWin = [], computerWin = [],chessManStatus = [], winCount = 0;       //所有獲勝的數(shù)量和數(shù)量統(tǒng)計(jì)
for(var i=0;i<15;i++) {
    wins[i] = []; chessManStatus[i] = [];
    for(var j=0;j<15;j++) {
        wins[i][j] = []; chessManStatus[i][j] = 0;
    }
}
for(var i=0;i<15;i++) {
    for(var j=0;j<11;j++) {
        for(var k=0;k<5;k++){
           wins[i][j+k][winCount] = true;
        }
        winCount++;
    }
}
for(var i=0;i<15;i++) {
    for(var j=0;j<11;j++) {
        for(var k=0;k<5;k++){
            wins[j+k][i][winCount] = true;
        }
        winCount++;
    }
}
for(var i=0;i<11;i++) {
    for(var j=0;j<11;j++) {
        for(var k=0;k<5;k++){
            wins[i+k][j+k][winCount] = true;
        }
        winCount++;
    }
}
for(var i=0;i<11;i++) {
    for(var j=14;j>3;j--) {
        for(var k=0;k<5;k++){
            wins[i+k][j-k][winCount] = true;
        }
        winCount++;
    }
}
for(var i=0; i

經(jīng)過(guò)通過(guò)棋盤(pán)上所有可能勝利的情況不過(guò)572種而已!

3.2 計(jì)算最合適的落棋目標(biāo)

如果我是計(jì)算機(jī),接下來(lái)我要做的就是當(dāng)“聰明的人類”下好棋之后,我怎樣下好自己的棋。這個(gè)棋的目標(biāo):不讓人類贏,讓自己贏!作為人類的我會(huì)大概看一下棋盤(pán)上的所有棋子,然后選好一個(gè)落棋點(diǎn),我很羨慕計(jì)算機(jī)的計(jì)算能力,如果我是它我就可以計(jì)算一下棋盤(pán)上的每一個(gè)坐標(biāo)點(diǎn),對(duì)它們的情況進(jìn)行評(píng)估打分,然后選得分最高的點(diǎn)下棋。當(dāng)然計(jì)算機(jī)就是這么做的,每一次下棋它都做了128700次計(jì)算來(lái)挑選出最合適的落子點(diǎn)。而進(jìn)行這么多次計(jì)算也不過(guò)是毫秒之間的事情,所以計(jì)算機(jī)下棋特別的快,快到“人類”看不出它的反應(yīng),幾乎和自己同時(shí)下棋的,或許你的棋子剛落下,它就贏了,感覺(jué)特別沮喪!

function computerAI() {      //電腦智能下棋
    var personScore = [],computerScore = [],maxScore = 0,curX = 0, curY = 0;
    for(var i=0; i<15; i++) {
       personScore[i] = [];computerScore[i] = [];
       for(var j=0; j<15; j++) {
           personScore[i][j] = 0;computerScore[i][j] = 0;
       }
    }
    for(var i=0; i<15; i++) {
        for(var j=0; j<15; j++) {
            if(chessManStatus[i][j] == 0) {
                for(var k=0; k maxScore) {
                    maxScore = personScore[i][j];
                    curX = i;
                    curY = j;
                }else if(personScore[i][j] == maxScore) {
                    if(computerScore[i][j] > computerScore[curX][curY]) {
                        curX = i;
                        curY = j;
                    }
                }
                if(computerScore[i][j] > maxScore) {
                    maxScore = computerScore[i][j];
                    curX = i;
                    curY = j;
                }else if(computerScore[i][j] == maxScore) {
                    if(personScore[i][j] > personScore[curX][curY]) {
                        curX = i;
                        curY = j;
                    }
                }
            }
        }
    }
    drawChessMan(curX, curY);
    ......
  }

這個(gè)打分算法是整個(gè)算法的核心。計(jì)算機(jī)將連在一起的棋子做打分,1個(gè)棋子分?jǐn)?shù)很低,只有200;兩個(gè)棋子就會(huì)翻到800;三個(gè)棋子會(huì)更高,冪次運(yùn)算。有了評(píng)分標(biāo)準(zhǔn)以后,計(jì)算機(jī)開(kāi)始評(píng)分,先給對(duì)手評(píng)分,給對(duì)手評(píng)完分?jǐn)?shù)后再給自己評(píng)分,計(jì)算機(jī)自己的評(píng)分規(guī)則比對(duì)手評(píng)分規(guī)則高,但是原則上是2個(gè)棋子連在一起的評(píng)分不會(huì)高于對(duì)手三個(gè)棋子連在一起的:計(jì)算機(jī)在自己贏之前是不會(huì)讓對(duì)手有贏的機(jī)會(huì)的。

3.4 游戲狀態(tài)判斷

那么游戲什么事件結(jié)束呢?當(dāng)然是有五個(gè)棋子連在一起就結(jié)束了。這些工作就交給計(jì)算機(jī)來(lái)做吧:計(jì)算機(jī)記錄每一個(gè)贏的情況下連珠棋子的個(gè)數(shù),當(dāng)有棋子達(dá)到5時(shí)游戲就結(jié)束了,當(dāng)然黑白棋子是互斥的,當(dāng)白棋在一個(gè)位置有連珠時(shí),黑棋就永遠(yuǎn)沒(méi)有機(jī)會(huì)了,我們?cè)诔绦蛏辖o它設(shè)置為6,不管它怎樣加連珠,都不可能是5了。初始化一個(gè)gameOver變量為false,標(biāo)識(shí)游戲是否結(jié)束,當(dāng)游戲結(jié)束時(shí),取反就行:gameOver = !gameOver了。

 for(var k=0; k
4.更多細(xì)節(jié)與感悟

我承認(rèn)自己代碼寫(xiě)的很爛,考慮不到很多優(yōu)化的情況。但是我把能想到的,能做到的還都是盡力做到了。比如我在一個(gè)已經(jīng)有棋子的地方點(diǎn)擊,是不會(huì)讓系統(tǒng)重新繪制棋子的;我在游戲結(jié)束之后,不會(huì)讓接下來(lái)的工作繼續(xù)進(jìn)行的;沒(méi)有重新開(kāi)始,沒(méi)有善后工作,這些就留想要做一個(gè)完美作品的人來(lái)做吧。寫(xiě)這個(gè)智能算法給我的感悟就是我更能夠像計(jì)算機(jī)一樣的去思考問(wèn)題了,人類的思考能力會(huì)受到情感的左右,而計(jì)算機(jī)不會(huì),一個(gè)越成熟的人,越會(huì)像計(jì)算機(jī)一樣,像程序一樣,做事情井然有序,受情感因素的干擾會(huì)很小。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98972.html

相關(guān)文章

  • BetaMeow----利用機(jī)器學(xué)習(xí)做子棋AI

    摘要:簡(jiǎn)言之,機(jī)器學(xué)習(xí)是內(nèi)功,而數(shù)據(jù)挖掘則是機(jī)器學(xué)習(xí)的一種用途。但本質(zhì)上是我在學(xué)習(xí)機(jī)器學(xué)習(xí)方面的實(shí)戰(zhàn)項(xiàng)目,所以我想辦法利用機(jī)器學(xué)習(xí)的方面的算法實(shí)現(xiàn)。 BetaMeow的起源 前段時(shí)間AlphaGo和李世石廣受關(guān)注,作為人工智能的腦殘粉,看完比賽后激動(dòng)不已,因?yàn)橛幸欢ǖ臋C(jī)器學(xué)習(xí)的基礎(chǔ),便打算擼一個(gè)棋類的AI,但我還算有點(diǎn)自知之明,圍棋AI,甚至google打算做得通用AI是做不出的了,所以打算...

    bingchen 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.23 - AlphaGo 兩連勝柯潔:“狗” 來(lái)了!

    摘要:的前世今生去年月,橫空出世,戰(zhàn)勝了韓國(guó)棋手李世石,贏下了人機(jī)對(duì)弈的第一戰(zhàn)。當(dāng)然,隨著技術(shù)的不斷發(fā)展,人工智能有望在所有領(lǐng)域完全超越人類,成為超人類智能,為人類文明的發(fā)展做出更大的貢獻(xiàn)。 showImg(https://segmentfault.com/img/bVOgwC?w=900&h=385); AlphaGo 的前世今生 去年 3 月,AlphaGo 橫空出世,4:1 戰(zhàn)勝了韓國(guó)...

    anquan 評(píng)論0 收藏0
  • Python實(shí)現(xiàn)AI子棋

    摘要:可以說(shuō),每個(gè)評(píng)估函數(shù)就是一個(gè)選手,對(duì)不同的棋型每個(gè)選手自然有不同的看法和應(yīng)對(duì)措施,當(dāng)然他們的棋力也就因此各不相同了。方搜索最大值,人類方搜索最小值。了解了上述原理之后,就可以自己寫(xiě)代碼實(shí)現(xiàn)了。 公眾號(hào):Charles的皮卡丘作者:Charles 開(kāi)發(fā)工具:Python版本:3.6.4相關(guān)模塊:graphics模塊。 環(huán)境搭建:安裝Python并添加到環(huán)境變量即可。 原理簡(jiǎn)介:對(duì)于五子棋...

    Yangder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<