Creation of a match 3 game like Farm Heroes Saga using any language – step 2

Read all posts about "" game

Are you ready for the next step of the creation of a game like Farm Heroes Saga? In first step I showed you the basic concepts of the game, now it’s time to start coding something real.

CREATION OF THE GAME FIELD

I told you we have a constant called FIELDSIZE which determines the side of the game field. We also know we are going to use a one-dimensional array because it’s easier to code in any language/prototype, and finally we have another constant called TILETYPES which stores the amount of different tile types we have in the game.

So the basic algorithm would say: “create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES” and guess what… it would work! Too bad in most cases you will get a starting array already filled with some matches already done: it’s very likely to have three or more items with the same tile type.

Do you want an example?

Let’s take this very very basic script, made with JavaScript:

var FIELDSIZE = 8;
var TILETYPES = 8;
var gameArray = new Array(FIELDSIZE*FIELDSIZE);

for(i=0;i<FIELDSIZE*FIELDSIZE;i++){
     gameArray[i]=Math.ceil(Math.random()*TILETYPES);
}

console.log(gameArray);

If you execute it with Google Chrome you will have a console output like this one:

[2, 6, 3, 2, 6, 4, 2, 6, 5, 2, 2, 2, 5, 3, 7, 6, 6, 4, 2, 4, 5, 2, 8, 6, 5, 1, 5, 3, 8, 5, 5, 6, 4, 4, 8, 4, 2, 2, 3, 1, 7, 4, 3, 4, 2, 2, 5, 6, 6, 1, 2, 7, 2, 7, 5, 7, 4, 2, 6, 6, 1, 8, 2, 5] 

You can clearly see items at indices 9, 10 and 11 have the same value, that is they form a match and we don’t want the player to start a level with a free match.

Also, I would like you to see there aren’t constants in JavaScript, so I used variables.

CREATION OF THE PERFECT GAME FIELD

The perfect game field is a game field filled with random values which do not form any free match. So our algorithm will change from “”create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES” to “create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES without free matches“.

That’s where things get complicated. To prevent matches during the creation of the game field, we have to be able to detect a match. Now it’s time to create the set of functions we discussed in first step, let’s make a recap:

rowNumber(i) – given a tile with array index i, will return the number of the row
colNumber(i) – basically works in the same way, operating on columns
isHorizontalMatch(i) – will say if a tile with array index i is part of an horizontal match
isVerticalMatch(i) – will say if a tile with array index i is part of a vertical match

This set of functions can be written in JavaScript this way:

function rowNumber(i){
     return Math.floor(i/FIELDSIZE);
}

function colNumber(i){
     return i%FIELDSIZE;
}

function isHorizontalMatch(i){
     return colNumber(i)>=2 && gameArray[i]==gameArray[i-1] && gameArray[i] == gameArray[i-2] && rowNumber(i)==rowNumber(i-2);
}

function isVerticalMatch(i){
     return rowNumber(i)>=2 && gameArray[i]==gameArray[i-FIELDSIZE] && gameArray[i] == gameArray[i-2*FIELDSIZE];
}

We already discussed about the logic behind these functions in first step but I would like to have a look at isHorizontalMatch function in the final AND condition where I specify both the i-th and the (i-2)th elements must be on the same row.

If I don’t specify this condition, since we have a one-dimensional array, it could happen we have two equal items in the last two position of a row, and an equal item in the first position of the next row, because the array is wrapping. Look at this picture:

Although the three highlighted carrots are basically next to each other, it’s not a valid match because they aren’t on the same row. This cannot happen when working on columns.

This way to create the perfect game field we have, for each item, to keep generating random values until it does not form a match, here it is the JavaScript example:

var FIELDSIZE = 8;
var TILETYPES = 8;
var gameArray = new Array(FIELDSIZE*FIELDSIZE);

for(i=0;i<FIELDSIZE*FIELDSIZE;i++){
     do{
          gameArray[i]=Math.ceil(Math.random()*TILETYPES);
     }while (isHorizontalMatch(i) || isVerticalMatch(i));
} 

console.log(gameArray);

function rowNumber(i){
     return Math.floor(i/FIELDSIZE);
}

function colNumber(i){
     return i%FIELDSIZE;
}

function isHorizontalMatch(i){
     return colNumber(i)>=2 && gameArray[i] == gameArray[i-1] && gameArray[i] == gameArray[i-2] && rowNumber(i) == rowNumber(i-2);
}

function isVerticalMatch(i){
     return rowNumber(i)>=2 && gameArray[i] == gameArray[i-FIELDSIZE] && gameArray[i] == gameArray[i-2*FIELDSIZE];
}

And this time the resulting array will represent a perfect game field. That was quite easy with JavaScript, but with some frameworks will require some more work, but we’ll dive into it next time, when we will place the gems on the stage.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers