在線網(wǎng)頁游戲框架(1)——走井游戲

走井是個古老的親子游戲,在電子游戲,電腦,手機(jī)沒有普及時間相信很多孩子都跟大人玩過這個游戲,沙地上找4個石子畫個框就能走起。不過為了讓電子時代的小鮮肉們也能知道后面在說什么,下面我們介紹一下走井游戲。

走井規(guī)則

走井的有兩名玩家,每個玩家有兩粒棋子,兩名玩家交替走子,當(dāng)一名玩家移動完自己的子之后,對方無子可動即獲得勝利?。


well.png

翻譯成計算機(jī)語言

按照上圖0,1,2,3,4這5個位置,列出每個位置的可移動狀態(tài),如下表

位置\可移動位置 0 1 2 3 4 十進(jìn)制 十六進(jìn)制
0 NA 1 1 1 1 31 0x1F
1 1 NA 1 0 0 5 0x5
2 1 1 NA 1 0 11 0xB
3 1 0 1 NA 1 21 0x15
4 1 0 0 1 NA 9 0x9

該表格查看方式類似于公交梯型票價圖,如按行查看,位置1可以的移動的目標(biāo)位置為 0,2,按位組合后為000101即十進(jìn)制數(shù)字5,十六進(jìn)制為0x5。其它的位置如查表即可得到。

將棋盤上唯的空位按照其所處的位置表示成一個5bit的數(shù)字,1的位置(可移動的目標(biāo)位置或者說是空著的位置)在5bit中來回移動。如開局時空為位于0,該值為00001--(hex)-->0x1。

SVG

一種矢量圖元描述格式,常用于作圖形軟件的數(shù)據(jù)交換。具體參見教程(內(nèi)網(wǎng))。
svg導(dǎo)學(xué)(互聯(lián)網(wǎng))
一個基本的svg結(jié)構(gòu)如下所示:

<html>
<body>

<h1>My first SVG</h1>

<svg width="100%" height="100%">
    <!---->
    <path d="M32 32 l128 0 l0 128 l-128 0 l128,-128" fill="none" stroke="black"></path>
    <line x1="32" y1="32" x2="160" y2="160" stroke="black" />

    <circle cx="96" cy="96" r="20" class="invisible" id='p0' />

    <circle cx="32" cy="32" r="20" class="gray" id='p1' />
    <circle cx="160" cy="32" r="20" class="black" id='p2' />

    <circle cx="160" cy="160" r="20" class="black" id='p3' />
    <circle cx="32" cy="160" r="20" class="gray" id='p4' />

    <rect id="turnSide" x="200" y="16" width="64" height="32" class="black"></rect> 
  </svg>
</body>
</html>

CSS 樣式

我們可以通過css模式直接控制svg元素的顯示屬性。

    .black {
      fill: black
    }

    .gray {
      fill: gray
    }

    .invisible {
      display: none
    }

我們定義黑色(black)、灰色(gray)、和不可見(invisible)三個顯示。

DOM事件

由于svg節(jié)點(diǎn)也是DOM節(jié)點(diǎn),DOM事件也是可用的,我們通過向節(jié)點(diǎn)增加click事件,來處理按鍵點(diǎn)擊。

function init() {
      
      elements = document.querySelectorAll('circle');

      for (var ele of elements) {
        console.log(ele);
        ele.addEventListener('click', pawnclick);
      }

    }

通過選擇器,選擇所有的circle標(biāo)簽,為它們增加點(diǎn)擊事件。

將邏輯連接起來

有了每個位置的可移動位置及當(dāng)前棋盤上的空位,我們可以通過位運(yùn)算得出點(diǎn)中子是否可移動,以及其移動的去向。如果子可動則把目標(biāo)位置置為當(dāng)前點(diǎn)擊位置的顏色(css class),點(diǎn)擊位置置為空(.invisible),并進(jìn)入下一手next()。下面是pawnclick()的實(shí)現(xiàn)。

    function pawnclick() {
      if (this.className.baseVal != current_player[round % 2]) {
        console.log('not your turn');
        return;
      }
      console.log(`click me ${this.id}`);

      //獲取可移動位置
      var moveDest = moveCandiate[this.id] & blankPos;
      if (moveDest != 0) {
        console.log(`move dest ${moveDest} boardPost ${mask2pos[moveDest]}`);

        blankPos = pos2mask[this.id];//將空位置為當(dāng)前子的位置

        //如果可以移動,則移動該子,并取消事件監(jiān)聽,進(jìn)入下一輪

        //獲取目標(biāo)位置
        var destPos = document.getElementById(mask2pos[moveDest]);
        destPos.className.baseVal = this.className.baseVal;
        this.className.baseVal = "invisible";

        nextTurn();//換手
      }
      else//沒有氣不可移動
      {
        console.log(`${this.id} 不可動`);
      }
    }

為了方便快速查找 翻譯成計算機(jī)語言中的表格,我們定義了 moveCandiate,mask2pos,pos2mask三個查找表。

var moveCandiate = {
      'p0': 0x1F,
      'p1': 0x5,
      'p2': 0xB,
      'p3': 0x15,
      'p4': 0x9
    };

    // 移動目標(biāo)位轉(zhuǎn)棋盤位置
    var mask2pos = {
      1: 'p0',
      2: 'p1',
      4: 'p2',
      8: 'p3',
      16: 'p4'
    }

    var pos2mask = {
      'p0': 1,
      'p1': 2,
      'p2': 4,
      'p3': 8,
      'p4': 16
    }

勝負(fù)判定

換手后++round,我們需要判斷當(dāng)前方是否還有子可動,如果無子可動則游戲結(jié)束。

function nextTurn()
    {
      ++round;
      var class_selector = current_player[round % 2];//根據(jù)手?jǐn)?shù)確定是哪邊
      document.getElementById('turnSide').className.baseVal = class_selector;
      var pawns = document.getElementsByClassName(class_selector);
      var hasMove = 0;
      for( var pawn of pawns)
      {
        hasMove |= (moveCandiate[pawn.id] & blankPos);
      }

      if(!hasMove)
      {
        console.log(`${class_selector} loose!`);
      }
      console.log(pawns);
    }

nextTurn()中還增加表示當(dāng)前移動方的指示方格document.getElementById('turnSide').className.baseVal = class_selector,對應(yīng)svg部分的<rect id="turnSide" x="200" y="16" width="64" height="32" class="black"></rect>

在線示例

本文代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容