Modern Full-Stack Development


Helper Function: canTileBeSelected()



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

 Helper Function: canTileBeSelected()
This function, in its entirety, is
canTileBeSelected : function(inLayer: number, inRow: number, inColumn: 
number): boolean {
  return
    (inLayer == 4 ||
      this.state.layout[inLayer + 1][inRow][inColumn] <= 0
    ) &&
    (inColumn === 0 || inColumn === 14 ||
      this.state.layout[inLayer][inRow][inColumn - 1] <= 0 ||
      this.state.layout[inLayer][inRow][inColumn + 1] <= 0
    );
}.bind(inParentComponent),
Chapter 11   time for fun: BattleJong, the Client


337
The test here is simple:
•  If the tile is in the topmost layer (4) OR there is no tile above it
•  AND if the tile is in the first (0) or last (14) column OR there is no tile 
to either the left or right of it
•  THEN it’s free, ELSE it’s not
At this point, we know that the tile can be selected, so we can start the real work, 
beginning with cloning the layout (since we’re going to alter it):
const layout: number[][][] = this.state.layout.slice(0);
Next, we need to see what the selected tile is, what its type is:
const currentTileValue: number = layout[inLayer][inRow][inColumn];
We need to determine that because of this next check:
if (currentTileValue <= 0) {
  return;
}
This keeps the player from trying to select a blank space.
Following that, we have to grab some other values out of state:
const scores: IScores = { ...this.state.scores };
let gameState: string = this.state.gameState;
let timeSinceLastMatch: number = this.state.timeSinceLastMatch;
let selectedTiles: ISelectedTile[] = this.state.selectedTiles.slice(0);
We need to clone scores because we might be updating it. Likewise, gameState 
might be changing (if they clear or dead-end the board), so that’s grabbed too. To 
determine how many points they get, if they match a pair (if this is the second tile being 
clicked), we will need to know how long it took, so timeSinceLastMatch is needed. 
Finally, one way or another, the values in selectedTiles will be changing regardless, so 
that gets cloned now too. Doing all of this now just makes the code later a bit cleaner and 
removes some redundancy.
Chapter 11   time for fun: BattleJong, the Client


338
With that done, the true logic can begin. First, we need to deal with the case where 
the tile they clicked was already highlighted. In that case, we want to de-highlight it. 
When a tile is highlighted, its tile type value gets 1000 added to it, so that’s the basic 
check:
if (currentTileValue > 1000) {
  layout[inLayer][inRow][inColumn] = currentTileValue - 1000;
  for (let i: number = 0; i < selectedTiles.length; i++) {
    const selectedTile: ISelectedTile = selectedTiles[i];
    if (selectedTile.layer == inLayer &&
      selectedTile.row == inRow &&
      selectedTile.column == inColumn
    ) {
      selectedTiles.splice(i, 1);
      break;
    }
  }
} else {
  layout[inLayer][inRow][inColumn] = currentTileValue + 1000;
  selectedTiles.push({ layer : inLayer, row : inRow,
    column : inColumn, type : currentTileValue });
}
First, we revert the value so that it’s back to just its basic tile type value (101–142). 
Next, we need to remove it from the selectedTiles array. Because this is an array and 
not a keyed object, we have little choice but to examine all members of the array; find 
the one that has the layer, row, and column value of the tile that was clicked; and then 
splice() that element out. There are several ways this code could be written, but I chose 
to just do a straight iteration over the array elements to find the match, then break out of 
the loop when found (I chose this route not for any specific reason other than it seemed 
simplest to me).
The else branch deals with the case where the tile wasn’t previously highlighted. In 
that case, we add 1000 to the tile type value to indicate it’s highlighted and then push an 
object into the selectedTiles array for this tile.
Chapter 11   time for fun: BattleJong, the Client


339
With the highlighting taken care of, we now need to see if there are two tiles selected, 
in which case we have some more work to do:
if (selectedTiles.length === 2) {
  if (selectedTiles[0].type === selectedTiles[1].type ||
    selectedTiles[0].type == 101 ||
    selectedTiles[1].type == 101
  ) {
If the type of both tiles matches, or if either of them is a wildcard (101), then that’s a 
matched pair. When that happens, we first must clear the pair by setting their tile type to 
–1 in the layout:
layout[selectedTiles[0].layer][selectedTiles[0].row]
  [selectedTiles[0].column] = -1;
layout[selectedTiles[1].layer][selectedTiles[1].row]
  [selectedTiles[1].column] = -1;
Recall that the PlayerBoard component won’t render anything in a given position 
when it sees a tile type of –1.
Next, it’s time to calculate how many points they get:
let calculatedPoints: number = 10;
const now: number = new Date().getTime();
const timeTaken: number = now - timeSinceLastMatch;
const numHalfSeconds: number = Math.trunc(timeTaken / 500);
calculatedPoints -= numHalfSeconds;
if (calculatedPoints <= 0) {
  calculatedPoints = 1;
}
scores.player += calculatedPoints;
timeSinceLastMatch = now;
The way this works is that they start with ten points for a match. From that, we 
subtract a point for every half a second taken. But we want to be nice here, so they always 
get a minimum of one point. Finally, the player’s score is updated (which is why the logic 
is what it is in the “update” message handler as you saw earlier), and we record the new 
time in timeSinceLastMatch so that we start counting from this moment toward their 
next match.
Chapter 11   time for fun: BattleJong, the Client


340
Next, we have to let the server know what happened via a "match" message:
this.state.socketComm.send(
`match_${this.state.pid}_${calculatedPoints}`
);
The server needs to know the player ID and how many points they got, so that’s the 
message that is constructed.
With that out of the way, the next task is to see if the board is either cleared or dead- 
ended. For that, another helper function is employed:
const anyMovesLeft: string = this.state.anyMovesLeft(layout);

Download 5,64 Mb.

Do'stlaringiz bilan baham:
1   ...   84   85   86   87   88   89   90   91   ...   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