HTML5 實現黑白棋遊戲|附代碼

2021-02-07 清華計算機學堂

2)初始化遊戲界面

遊戲開始時,init()對保存棋盤上的棋子信息的qizi數組初始化,同時在棋盤上顯示初始的4個棋子。

function init(){
             initLevel();// 棋盤上初始4個棋子
             showMoveInfo();//當前走棋方信息
             mycanvas.addEventListener("mousedown",doMouseDown,false); 
         }
         function initLevel() {
//初始化界面
var i,j;
for (i=0; i<8; i++) {
qizi[i]=new Array();
for (j=0; j<8; j++) {
qizi[i][j]=KONG;
}
}
// 棋盤上初始4個棋子
// 1為黑,2為白,0為無棋子
qizi[3][3] = WHITE;
qizi[4][4] = WHITE;
qizi[3][4] = BLACK;
qizi[4][3] = BLACK;
DrawMap();  //畫棋盤和所有棋子
message_txt.innerHTML = "該黑棋走子";
}
 //畫棋盤和所有棋子
        function DrawMap( )
        {
            context.clearRect ( 0 , 0 ,720 , 720); 
            context.drawImage(qipan,0,0,qipan.width,qipan.height);
        for(i=0;i<qizi.length;i++)//行號
        {
        for(j=0;j<qizi[i].length;j++)//列號
        {
        var pic;
        switch (qizi[i][j])
        {
        case KONG:                //0
        break;
        case BLACK:               //1
            pic = blackstone;
            context.drawImage(pic, w * j, h * i, pic.width, pic.height);
        break;
        case WHITE:               //2
            pic = whitestone;
            context.drawImage(pic, w * j, h * i, pic.width, pic.height);
        break;
        }
        }
        }
        }

showMoveInfo()顯示輪到那方走棋。

function showMoveInfo(){
             if (curQizi== BLACK)// 當前走棋方是黑棋
                  message_txt.innerHTML="該黑棋走子";
             else
                  message_txt.innerHTML="該白棋走子";
         }

init()函數同時對canvas添加滑鼠單擊事件的偵聽。如果canvas被單擊則執行doMouseDown函數完成走棋功能。

3)走棋過程

如果是棋盤被單擊,則此位置像素信息(event.pageX,event.pageY)可以轉換成棋盤坐標 (x1,y1),然後判斷當前位置(x1, y1)是否可以放棋子(符合夾角之勢),如果可以則此位置顯示自己棋子圖形,調用FanALLQi(i, j)從左,左上,上,右上等八個方向翻轉對方的棋。最後判斷對方是否有棋可走,如果對方可以走棋則交換走棋方。如果對方不可以走棋,則自己可以繼續走棋,直到雙方都不能走棋,顯示輸贏信息。

 function doMouseDown(event) { 
             var x = event.pageX; 
             var y = event.pageY; 
             var canvas = event.target; 
             var loc = getPointOnCanvas(canvas, x, y); 
             console.log("mouse down at point( x:" + loc.x + ", y:" + loc.y + ")"); 
             clickQi(loc);             
         }
     function getPointOnCanvas(canvas, x, y) { 
             var bbox = canvas.getBoundingClientRect(); 
             return { x: x - bbox.left * (canvas.width / bbox.width),
                      y: y - bbox.top * (canvas.height / bbox.height)};
         }
    function clickQi(thisQi) {
var x1, y1;
x1 = Math.round((thisQi.y - 40) / 80);  
y1 = Math.round((thisQi.x - 40) / 80); //Math.round()四捨五入
if (Can_go(x1, y1)) {// 判斷當前位置是否可以放棋子
//trace("can");
qizi[x1][y1] = curQizi;
FanALLQi(x1, y1);//從左,左上,上,右上,右,右下,下,左下方向翻轉對方的棋
DrawMap();
//判斷對方是否有棋可走,如有交換走棋方
if (curQizi==WHITE &&checkNext(BLACK) ||curQizi==BLACK &&checkNext(WHITE)) {
if (curQizi==WHITE) {
curQizi=BLACK;
message_txt.innerHTML = "該黑棋走子";
} else {
curQizi=WHITE;
message_txt.innerHTML = "該白棋走子";
}
} else if (checkNext(curQizi)) {
                       //判斷自己是否有棋可走,如有,給出提示
                        message_txt.innerHTML = "對方無棋可走,請繼續";
} else {//雙方都無棋可走,遊戲結束,顯示輸贏信息
isLoseWin();
}//統計雙方的棋子數量,顯示輸贏信息。
}
            else {
                message_txt.innerHTML = "不能落子!";
}
}

4)可否落子判斷

Can_go(x1,y1)從左,左上,上,右上,右,右下,下,左下八個方向判斷(x1,y1)處可否落子。

function Can_go( x1,  y1){
//從左,左上,上,右上,右,右下,下,左下八個方向判斷
if (CheckDirect(x1, y1, -1, 0) == true) {
return true;
}
if (CheckDirect(x1, y1, -1, -1) == true) {
return true;
}
if (CheckDirect(x1, y1, 0, -1) == true) {
return true;
}
if (CheckDirect(x1, y1, 1, -1) == true) {
return true;
}
if (CheckDirect(x1, y1, 1, 0) == true) {
return true;
}
if (CheckDirect(x1, y1, 1, 1) == true) {
return true;
}
if (CheckDirect(x1, y1, 0, 1) == true) {
return true;
}
if (CheckDirect(x1, y1, -1, 1) == true) {
return true;
}
return false;
}

CheckDirect()判斷某方向上是否形成夾擊之勢,如果形成且中間無空子則返回True。

  function CheckDirect( x1,  y1,  dx,  dy){
            var x,y;
            var flag= false;
            x = x1 + dx;
            y = y1 + dy;
            while (InBoard(x, y) && !Ismychess(x, y) && qizi[x][y] != 0) {
                x += dx;
                y += dy;
                flag = true;//構成夾擊之勢
            }
            if (InBoard(x, y) && Ismychess(x, y) && flag == true) {
                return true;//該方向落子有效
            }
            return false;
        } 

checkNext(i)驗證參數代表的走棋方是否還有棋可走。

/**
 * 驗證參數代表的走棋方是否還有棋可走
 * @param i   代表走棋方,1為黑方,2為白方
 * @return true/false
 */
function checkNext(i){
            old=curQizi;
            curQizi=i;
if ( Can_Num()>0) {
                curQizi=old;
return true;

            else {
                curQizi=old;
return false;
}

Can_Num()統計可以落子的位置數。

 function Can_Num() {//統計可以落子的位置數
            var i, j, n = 0;
            for (i = 1; i <= 8; i++) {
                for (j = 1; j <= 8; j++) {
                    if (Can_go(i, j)) {
                        n = n + 1;
                    }
                }
            }
            return n;//可以落子的位置個數
         }

5)翻轉對方的棋子

FanALLQi(int x1, int y1) 從左,左上,上,右上,右,右下,下,左下八個方向翻轉對方的棋子。

function FanALLQi(x1, y1) {
//從左,左上,上,右上,右,右下,下,左下八個方向翻轉
if (CheckDirect(x1, y1, -1, 0) == true) {
DirectReverse(x1, y1, -1, 0);
}
if (CheckDirect(x1, y1, -1, -1) == true) {
DirectReverse(x1, y1, -1, -1);
}
if (CheckDirect(x1, y1, 0, -1) == true) {
DirectReverse(x1, y1, 0, -1);
}
if (CheckDirect(x1, y1, 1, -1) == true) {
DirectReverse(x1, y1, 1, -1);
}
if (CheckDirect(x1, y1, 1, 0) == true) {
DirectReverse(x1, y1, 1, 0);
}
if (CheckDirect(x1, y1, 1, 1) == true) {
DirectReverse(x1, y1, 1, 1);
}
if (CheckDirect(x1, y1, 0, 1) == true) {
DirectReverse(x1, y1, 0, 1);
}
if (CheckDirect(x1, y1, -1, 1) == true) {
DirectReverse(x1, y1, -1, 1);
}
}

DirectReverse()針對已形成夾擊之勢某方向上的對方棋子進行翻轉。

 function DirectReverse(x1, y1, dx, dy) {
var x, y;
var flag= false;
x = x1 + dx;
y = y1 + dy;
while (InBoard(x, y) && !Ismychess(x, y) && qizi[x][y] != 0) {
x += dx;
y += dy;
flag = true;//構成夾擊之勢
}
if (InBoard(x, y) && Ismychess(x, y) && flag == true) {
do {
x -= dx;
y -= dy;
if ((x != x1 || y != y1)) {
FanQi(x, y);
}
} while ((x != x1 || y != y1));
}
}

FanQi(int x, int y)將存儲(x, y)處棋子信息qizi[x][y]的反色處理。

 function FanQi(x, y) {
if (qizi[x][y] == BLACK) {
qizi[x][y] = WHITE;

else {
qizi[x][y] = BLACK;
}
}

InBoard()判斷(x,y)是否在棋盤界內,如果在界內則返回真,否則返回假。

//InBoard()判斷(x,y)是否在棋盤界內,如果在界內則返回真,否則返回假。
 function InBoard(x,y ){
if (x >= 0 && x <= 7 && y >= 0 && y <= 7) {
return true;
} else {
return false;
}
}

6)顯示執棋方可落子位置

「走棋提示」按鈕單擊事件函數是DoHelp(),它顯示可以落子的位置提示。Show_Can_Position()用圖片i顯示可以落子的位置。

 function DoHelp() {
            showCanPosition();//顯示可以落子的位置
        }
        function showCanPosition() {
            //顯示可以落子的位置
            var i,j;
            var n = 0;//可以落子的位置統計
            for (i = 0; i <= 7; i++) {
                for (j = 0; j <= 7; j++) {
                    if (qizi[i][j] == 0 && Can_go(i, j)) {
                      n = n + 1;
                      pic=info;
                      context.drawImage(pic,w*j+20,h*i+20,pic.width,pic.height);;//顯示提示圖形
                    }
                }
            }
        }

7)判斷勝負功能

isLoseWin()統計雙方的棋子數量,顯示輸贏信息。

 // 顯示輸贏信息
         function isLoseWin() {
            var whitenum = 0;
            var blacknum = 0;
            var n = 0,x,y;
            for (x = 0; x <= 8; x++) {
                for (y = 0; y <= 8; y++) {
                    if (qizi[x][y] != 0) {
                        n = n + 1;
                        if (qizi[x][y] == 2) {
                            whitenum += 1;
                        }
                        if (qizi[x][y] == 1) {
                            blacknum += 1;
                        }
                    }
                }
            }
            if (blacknum > whitenum) {
                message_txt.innerHTML = "遊戲結束黑方勝利,黑方:" + String(blacknum) + "白方:" + String(whitenum);
            } else {
                message_txt.innerHTML = "遊戲結束白方勝利, 黑方:" + String(blacknum) + "白方:" + String(whitenum);
            }
        }

相關焦點

  • 百行 HTML5 代碼實現四種雙人對弈遊戲
    需要 說明的是,圍棋,五子棋等這些棋子都是圓的啊,請不要為了圖片苦惱,在 HTML5 時代,我們用代碼就可以實現立體圓形棋子;第三步:判斷落子事件。當然是要定位手指的點擊位置,這四種棋中,有的是落在框裡面的,有的卻是落在縱橫交錯的 棋盤十字線上,需要動態處理;第四步:判斷落子規則。下棋都有規則,不要因為代碼少,就將規則打折扣,否則程序不成熟,會變成小朋友的玩具了;第五步:判 斷輸贏。
  • HTML技巧篇:實現元素水平與垂直居中的幾種方式
    本篇文章主要給大家介紹一下如何使用html+css實現元素的水平與垂直居中效果,這也是我們網頁在編碼製作中會經常用到的問題。200px;就可以實現文字的居中效果,具體的代碼如下所示:由上圖可以看出我們實現了單行文字的垂直居中效果,但是很多時候我們的文字並不知道具體有多少,可能有一行,也可能有很多行,那麼遇到多行文字的這種問題我們要如何處理呢。
  • html中的a標籤,超連結代碼的詳細介紹
    今天為大家介紹的是超連結代碼a標籤的用法,大家有興趣的話可以看看喲!隨著網際網路的發展,網站的興起,超連結隨處可見。我們使用電腦或手機上網,能夠穿梭在各個網頁之間,都是通過超連結實現的。超連結就像通向另一個「 世界」的橋梁,我們可以通過它到達另一個「世界」。接下來我們就來學習一下網頁中的超連結到底是什麼東西。
  • 用css配合HTML代碼製作導航條下拉麵板
    首先我們來看看下拉麵板的效果吧,這個事稍微複雜一點的下拉麵板,我們會一步步為您講解,如何製作出這樣一個下拉麵板,但前提是你需要了解CSS的定位知識和HTML代碼,因此沒有這些基礎的同學要先學一下HTML代碼和CSS(層疊樣式表)的知識。
  • JavaScript通過DOM修改Html內容、Html屬性和Html標記style樣式
    現在我們運行一下此html文件,看一下運行結果是什麼:getElementById()獲取html元素在此代碼中,通過getElementById()方法找到id為div1的Html元素,然後使用innerText設置一個文本值。
  • html如何製作分頁
    一般的製作頁面都會使用到分頁,那麼你知道分頁功能是怎麼實現的嗎?讓我們一起來學習一下html如何製作分頁吧。新建html頁面。如圖:在html頁面找到body標籤,在body標籤裡新建一個div標籤,然後在div標籤中新建a標籤,並在a標籤中輸入頁數。
  • 用TensorFlow基於神經網絡實現井字棋(含代碼)
    這能看出神經網絡算法模型能否生成以前未有過的走棋(即該走棋不在訓練集中);第二種評估的方法是,直接實戰井字棋遊戲看是否能贏。 不同的棋盤位置列表和對應的最佳落子點數據在 GitHub [1] 中可以查看。
  • jQuery中使用text()、html()、val()方法對Html元素賦值和取值
    的html()方法與text()方法,都是給非表單元素賦值和取值的,但是html()功能更強大一些,還可以給元素賦的值是html代碼。</span></div></body></html>此代碼中,使用了html()方法獲取div1元素帶有html代碼的值。
  • html菜鳥教程,HTML新手如何快速入門
    首先來認識一下HTML:HTML是一種超文本標記語言,目前已經發展到了第五代:HTML5。支持代碼自動縮進,格式化HTML代碼,支持快捷鍵注釋和自動保存。對於CSS和JS的引用,也能夠快速的讀取磁碟相對路徑,進而自動補充。在寫代碼的效率上提升不少。3、HBuilder,這個是後期專業做前端的開發工具,除了html以及js等的代碼編寫之外,還有自帶了容器啟動,頁面可以隨時瀏覽並刷新。
  • 使用HTML DIV+CSS樣式+JavaScript實現自定義個性化的模態窗口
    DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title></title>
  • 六道黑白棋佔角謎題
    黑白棋是我最喜歡的棋類遊戲之一。
  • 整個網頁變成灰色的代碼是什麼?如何讓網站變成灰色?
    問:整個網頁變成灰色的代碼是什麼?答:使這個網頁的顏色變成灰色的最簡單的方法,就是在當前頁面的css裡面。添加下面的代碼,並且讓他在任意的瀏覽器裡面正確的執行,html{    -webkit-filter:grayscale(100%);    -moz-filter:grayscale(100%);    -ms-filter
  • 每天進步一點點,html常用標籤介紹
    有時需要使用html標籤實現各種各樣的需求,所以html標籤會有很多,常用的html標籤也會有很多,今天我們繼續來學習html常用標籤。1、圖片標籤;圖片標籤為<img>,它有一個很重要的屬性就是src,scr指的是圖片的路徑,在瀏覽網頁的時候上面也會出現很多圖片,請看下面實現代碼;下面代碼中有一點需要解釋,就是src如何寫,可以看到下圖中src寫的是..
  • 《代碼整潔之道》:5大基本要點
    ("<hr"); if (size >0) html.append(" size="").append(size + 1).append("\""); html.append(">");
  • 零代碼,用 HTML5 驚豔朋友圈 – MAKA
    HTML5 頁面流行的風停不下來,連招聘、邀請、宣傳都變得如此精緻,羨慕的同時你有沒有手癢的感覺?除了變身程式設計師苦逼地寫代碼之外,你還有一條路可以走。號稱「全宇宙最強大的 H5 製作神器」MAKA App 就在這裡,功能絕對讓你驚豔。
  • 如何用一行代碼實現網頁變灰效果?
    其實,解決方案很簡單,只需要幾行代碼就能搞定了。實現我們選擇一個網站,比如 B 站吧,打開瀏覽器開發者工具。審查一下網頁的原始碼,我們可以發現在 html 的這個地方多了一個疑似的 class,叫做 gray,gray 中文即灰色。
  • 這些廢棄的 HTML 標籤不要用
    <blink>可以實現閃爍效果,例如:<blink>Why would somebody use this?DOCTYPE html><html><frameset cols="25%,*,25%">  <frame src="frame_a.htm">  <frame src="frame_b.htm"> <frame src="frame_c.htm"></frameset></html>注意:
  • DIV CSS3和html5 CSS3有什麼區別
    首先,不管是DIV+CSS3還是html5+CSS3,他們都是我們對網頁開發布局方式的統稱,但是DIV+CSS3作為網頁的基礎開發這句話其實並不嚴謹,因為而div只是HTML的一個比較重要的元素而已,而標準的叫法應是HTML+CSS,我們要比較的其實是html+css3和html5+css3在布局開發到底有什麼不同
  • 實戰|Python輕鬆實現動態網頁爬蟲(附詳細源碼)
    靜態網頁,隨著html代碼的生成,頁面的內容和顯示效果就基本上不會發生變化了——除非你修改頁面代碼。而動態網頁則不然,頁面代碼雖然沒有變,但是顯示的內容卻是可以隨著時間、環境或者資料庫操作的結果而發生改變的。——來源百度百科動態網頁具有減少工作量、內容更新快、可完成功能多等特點,被很多公司所採用,比如狗東、某寶、某瓣、某乎等等。
  • html5 文本相關標籤(基礎三)
    html5 文本相關標籤一、標題 h1、h1、hgroup(標題組)1、什麼情況下使用標題?02.副標題3、標題組 hgroup01.當主標題和副標題成組時,應使用hgrouphgroup h1h24、標題級別問題01.html5