Modern Full-Stack Development


Helper Function: anyMovesLeft( )



Download 5,64 Mb.
Pdf ko'rish
bet89/107
Sana06.08.2021
Hajmi5,64 Mb.
#140576
1   ...   85   86   87   88   89   90   91   92   ...   107
Bog'liq
Modern Full-Stack Development Using TypeScript, React, Node

 Helper Function: anyMovesLeft( )
The anyMovesLeft() function is somewhat complicated, so let’s break it down into bite- 
sized nuggets:
anyMovesLeft : function(inLayout: number[][][]): string {
  let numTiles: number = 0;
  const selectableTiles: number[] = [ ];
  for (let l: number = 0; l < inLayout.length; l++) {
    const layer = inLayout[l];
    for (let r: number = 0; r < layer.length; r++) {
      const row = layer[r];
      for (let c: number = 0; c < row.length; c++) {
        const tileVal: number = row[c];
        if (tileVal > 0) {
          numTiles += 1;
          if (this.state.canTileBeSelected(l, r, c)) {
            if (tileVal === 101) {
              return "yes";
            }
            selectableTiles.push(tileVal);
          }
        }
      }
    }
  }
Chapter 11   time for fun: BattleJong, the Client


341
Remember that it’s the cloned layout array that we need to examine right now 
because the layout property in state hasn’t been updated yet, so that’s why it gets passed 
to anyMovesLeft(). Once there, the first task is to get a list of all free tiles. To do this, we 
need to iterate through the entire layout – and remember it’s a three-dimensional array. 
Thus, we have nested loops here – and for each, call the canTileBeSelected() function.
Now, if a tile is determined to be free, and it’s a wildcard, then we automatically 
know that the board has not dead-ended because a wildcard can match any other tile 
type. And, because we start with an even number of tiles, and they only ever get removed 
in pairs, that means that there must be at least two tiles left. Therefore, there is at least 
one move left for sure and we can short-circuit this function by returning “yes” right 
then and there.
Otherwise, the tile is pushed into the selectableTiles array for further scrutiny. 
That scrutiny begins with a simple check:
if (numTiles === 0) {
  return "cleared";
}
Obviously, if there are no tiles at all, then there can be no more moves left! This case 
means that the player just cleared the board, so we let the caller know with the return 
value “cleared”. By the way, this should make it apparent now why this function can’t 
return a simple boolean true or false: because there are actually three outcomes! There 
could be a move left, there could be no moves left due to a dead end, or there could be 
no moves left due to the board being cleared. The caller needs to differentiate those 
outcomes, so a string is returned instead.
At this point, we know that there are still selectable tiles, and we know that there are 
no wildcards (i.e., no selectable wildcards – there still could be some unselectable ones). 
Therefore, the next trick is to see if there are any matches.
Your initial thought here might be that you would need to iterate over this array and 
compare each element to every other element to find at least one match. And certainly, 
that would work. But there is a more efficient approach:
const counts: number[] = [];
for (let i: number = 0; i < selectableTiles.length; i++) {
  if (counts[selectableTiles[i]] === undefined) {
    counts[selectableTiles[i]] = 1;
Chapter 11   time for fun: BattleJong, the Client


342
  } else {
    counts[selectableTiles[i]]++;
  }
}
First, you count how many times each tile type occurs. This uses an associative array, 
meaning that the tile type becomes the key of an array element. With that done, the 
check to see if there are any matches left becomes very simple:
for (let i: number = 0; i < counts.length; i++) {
  if (counts[i] >= 2) {
    return "yes";
  }
}
That’s it! If any element of the array has a value greater than or equal to two, then 
that means there is a match left to be made because, remember, we already checked that 
these tiles are selectable.
If there are no such values found in the array, then the final possible return value is 
returned:
  return "no";
So, jumping back to the code in tileClick(), now that we know if there are any 
moves left, we can act accordingly:
switch (anyMovesLeft) {
  case "no":
    gameState = "deadEnd";
    this.state.socketComm.send(`done_${this.state.pid}`);
  break;
  case "cleared":
    scores.player += 100;
    gameState = "cleared";
    this.state.socketComm.send(`match_${this.state.pid}_100`);
    this.state.socketComm.send(`done_${this.state.pid}`);
  break;
}
Chapter 11   time for fun: BattleJong, the Client


343
A return from anyMovesLeft() of “no” indicates a dead-ended board, so gameState is 
transitioned to that state, and the server is notified that this player is done. A return value 
of “cleared” indicates the board was cleared, in which case we give them a point bonus, 
in addition to transitioning gameState and telling the server that they are finished. Note 
that we must send two messages here because the server needs to know about the point 
bonus too. There’s no special message for that, though; we simply tell the server that 
another match occurred via the “match” message. It doesn’t matter that one technically 
hasn’t occurred. The server only needs the number of points to add here, so we can force 
that message to do double duty.
Now, all that logic was for dealing with a pair of tiles being selected, but what 
happens if this tile click event was the second tile of an unmatched pair? Well, that’s 
where the else branch of the opening if statement comes in:
} else {
  layout[selectedTiles[0].layer][selectedTiles[0].row]
    [selectedTiles[0].column] =  layout[selectedTiles[0].layer]
[selectedTiles[0].row]
        [selectedTiles[0].column] - 1000;
  layout[selectedTiles[1].layer][selectedTiles[1].row]
    [selectedTiles[1].column] =  layout[selectedTiles[1].layer]
[selectedTiles[1].row]
        [selectedTiles[1].column] - 1000;
}
In this situation, all we need to do is revert the tile value of the two tiles to their 
101–142 range, and we’re done.
Regardless of whether we just handled a matched pair or not, both tiles would be 
either cleared or de-selected now, so they need to be removed from selectedTiles:
selectedTiles = [ ];
Only one thing remains to be done, but it is absolutely key:
this.setState({
  gameState : gameState,
  layout : layout,
  selectedTiles : selectedTiles,
Chapter 11   time for fun: BattleJong, the Client


344
  scores : scores,
  timeSinceLastMatch : timeSinceLastMatch
});
None of the code in tileClick() to this point will have altered state, but that needs 
to occur lest nothing change on the screen! So, a quick call to setState() takes care of it. 
I didn’t want to introduce any sort of conditional updates here either; I figured it was 
easier just to update everything that could have changed, whether it actually did or not.
And with that, our journey through BattleJong is complete!

Download 5,64 Mb.

Do'stlaringiz bilan baham:
1   ...   85   86   87   88   89   90   91   92   ...   107




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish