\documentclass{article}

\usepackage[T1]{fontenc}

\usepackage{hyperref}
\usepackage{graphicx}
\usepackage[style=authoryear,backend=biber]{biblatex}
\usepackage[margin=1in]{geometry}
\usepackage[divipsnames]{xcolor}
\usepackage{float}
\usepackage{minted}
\usepackage{algorithm}
\usepackage{setspace}
\usepackage{etoolbox}
\usepackage{mathtools}
\usepackage{sourcecodepro}
\usepackage{algpseudocode}
\usepackage{mdframed}
\usepackage{pgfplots}
\usepackage{changepage}

\mdfsetup{skipabove=0pt,skipbelow=0pt}

\spaceskip=1mm

\makeatletter
\renewcommand{\ALG@name}{Pseudocode}

\bibliography{ref}

\setlength\parindent{0pt}
\setlength\parskip{0.5em}

\BeforeBeginEnvironment{minted}{\smallskip}
\AfterEndEnvironment{minted}{\smallskip}

\AtBeginEnvironment{minted}{\setstretch{1.2}}

\definecolor{palegreen}{RGB}{248, 255, 248}
\definecolor{graymetal}{RGB}{208, 226, 234}
\definecolor{navyblue}{RGB}{24, 64, 146}
\definecolor{matteblue}{RGB}{72, 114, 195}

\hypersetup{
	colorlinks = true,
	urlcolor   	= matteblue,
	filecolor 	= navyblue
	linkcolor	= matteblue,
	citecolor	= navyblue
}

\begin{document}
\begin{titlepage}
\pagecolor{palegreen}
\centering
\vspace*{0.3cm}

\Huge
\begin{mdframed}[
	backgroundcolor=graymetal,
	linecolor=black,
	rightline=false,
	leftline=false,
	linewidth=4pt,
	innertopmargin=1.75cm,
	innerbottommargin=1.75cm
]
\centering

\textbf{2D \ \ Procedural \ \ Map \ \ Generation}

\huge
\vfill
\
\textbf{With Pascal \& SwinGame}
\end{mdframed}

\vfill

\begin{tikzpicture}
\begin{axis}[
width=0.8\textwidth,
height=0.8\textwidth,
xlabel=$x$,
ylabel=$y$,
hide axis]
\addplot3[surf,
colormap/cool,
domain=0:1]
{sin(deg(8*pi*x))* exp(-20*(y-0.5)^2)
+ exp(-(x-0.5)^2*30
- (y-0.25)^2 - (x-0.5)*(y-0.25))};
\end{axis}
\end{tikzpicture}

\vfill
\large
\textbf{Jacob Milligan \\ \small Student ID - 100660682}

\end{titlepage}
\clearpage
\nopagecolor
\hypersetup{linkcolor=navyblue}
\tableofcontents
\hypersetup{linkcolor=blue}

\clearpage

\section{Procedural Generation}

\subsection{Procedural over Manual}

Very broadly speaking, in game development there are two primary ways to generate content for a project. The most common and controllable way is to produce each piece of content by hand. The consequences, in the case of this article, would be the production of a large 2D tile map by a manual process.

For smaller content sizes this isn't a problem; it's a relatively straight-forward process to declare each tile as an element of a statically-sized 2D array and just draw those tiles to the screen in a single pass alongside, perhaps, the drawing of different sprites layered on top of each tile to represent NPC's or the player. But what happens as a map grows in size? As it increases from a $32 \times 32$ map to a $256 \times 256$ sized map, or even larger? Even if the programmer had created a time-saving, high-level system for creating maps as text files to be read in by the program, it can very quickly become time-consuming and tedious. Although this is a valid way of generating content, in fact the developers on CD Projekt Red's The Witcher 3: Wild Hunt did just that \parencite{witcher}, most programmers don't possess the resources or manpower of a AAA game studio and therefore often must create a better solution. So what's the appropriate solution?

\paragraph{Procedural Generation algorithms are the solution}\mbox{}

Indie game title such as Minecraft, Dwarf Fortress, and the upcoming No Mans Sky all make use of procedural content generation to build enormous, beautiful, but seemingly random and unique worlds. We say \emph{seemingly} random for two reasons:
\begin{enumerate}
\item
Computers can only produce \emph{pseudo}-random numbers as the only truly random processes are analog, physically occurring phenomena, such as the measurement of cosmic radiation or noise signals in hardware circuits \parencite{guneysu}.
\item
These procedural generation algorithms are designed so that, with the same starting point, it will produce the same result.
\end{enumerate}

\paragraph{What is the starting point for this process?}\mbox{}

The answer to that question is wide and varied and many games, such as in indie title Dwarf Corp., begin by simulating tectonic plate activity \parencite{dwarfcorp}, erosion, or river formation to carve out their terrain -  in a similar fashion to how terrain forms in the real world \parencite[pp. 46]{huggett}. However, this article will be taking a different route and begin by generating a realistic height map stored in a 2D array of elements that each hold a generated elevation value which will be used to base the remaining generation procedures off. We will use this initial information to procedurally generate a $512 \times 512$ sized 2D continent-like map that can be navigated by a player character. Furthermore, we will make heavy use of the SwinGame API to handle all graphics-related functionality and briefly touch on other interesting concepts such as basic collision detection and drawing algorithms, all of which will be coded using the Pascal programming language.

\subsection{Diamonds \& Squares}

To generate a heightmap, it would be possible to design an algorithm from scratch, however that would take a long time, would need to be rigorously tested, and the result probably wouldn't be very effective, so the core of our program will be based off a very well-known and  well-tested one named \textbf{Random Midpoint Displacement} \parencite{fournier}, also known as \textbf{the Diamond-Square Algorithm}. At its core, the purpose of this algorithm is to generate pseudo-random noise in a desirable pattern, i.e. one that resembles a realistic spread of terrain height values. Each point of noise is stored in a data structure, in our case a 2D array, and holds a single value - a number representing its elevation. The resulting map will look something like this:

\begin{figure}[H]
	\centering
	\includegraphics{map.jpg}
	\renewcommand{\figurename}{Example}
	\caption{A map generated using Diamond-Square}
\end{figure}

\paragraph{The basic concept behind Diamond-Square can be summed up like so:}

\begin{itemize}

	\item
		Take an empty grid, which must be of size \(2^{n}+1\) in order for the following steps to function correctly. Then assign the corners a \emph{seed} value, a number that all other calculations are based off. This will mean that with the same seed, the same result should be produced. Then iterate the following two steps:
	\begin{itemize}
		\item
			\textbf{The Sqaure Step} - Take the grids four corners, average their total, find their mid point and assign that point the 				average plus a random value up to the maximum defined height of the map.
		\item
			\textbf{The Diamond Step} - Given the previous step, we now have a diamond shape of four points surrounding a new mid 			point. Take the average of all points in the diamond and assign the new midpoint that value plus a random amount up to the 			maximum defined height value.
	\end{itemize}
	\item
		Use a \mintinline{Pascal}{nextStep} variable to determine which point in each diamond and square step to calculate.
	\item
		Iterate until \mintinline{Pascal}{nextStep} is less than zero.

\end{itemize}

This process can be best visualized using graphs, seen in the example pictured below.

\begin{figure}[H]
	\centering
	\includegraphics[width=0.9\linewidth,trim=4 4 4 4,clip]{diamondsquare.eps}
	\renewcommand{\figurename}{Example}
	\caption{Summary of the Diamond-Square algorithm}\label{fig:graph}
\end{figure}

\paragraph{Using this algorithm provides the ability to generate a starting point.}
However, before beginning an implementation, as with all software development, it would be wise to define the requirements for the final program - the functions, procedures, data structures, and features that should be included:
\begin{itemize}

\item
	First, we'll need a \mintinline{pascal}{Tile record} to hold data related to each tile in the map such as collision value, its associated bitmap, it's terrain type, and elevation. We'll also need a \mintinline{pascal}{MapData record} to contain our tile grid, the players sprite and location data, and its total size.
\item
	We'll need two primary terrain generation procedures - \mintinline{pascal}{DiamondSquare()} \& \mintinline[breaklines]{pascal}{GenerateTerrain()}. \mintinline{pascal}{DiamondSquare()} will be responsible for creating a new heightmap for a given \mintinline{pascal}{MapData()} parameter, whereas \mintinline{pascal}{GenerateTerrain()} will be responsible for deciding how each tile should be rendered based off the heightmap, alongside generating trees on the new \mintinline{pascal}{MapData's} tile grid.
\item
	Now that the terrain generation functions and data structures are defined, we'll also need a \mintinline{pascal}{CreateMap()} function to call both of the above procedures and to search for an appropriate place on the map to spawn the player.
\item
	Finally, we'll need both a \mintinline{pascal}{HandleInput()} procedure and a \mintinline{pascal}{DrawMap()} procedure to move the player around while detecting collision tiles and to draw the tile grid to the screen respectively.

\end{itemize}

There will also be several functions and resources referenced later on that we won't be building as they aren't directly related to procedural generation and are just utilities for allowing our map to render properly. This code sits in the \mintinline{pascal}{MapUtils.pas} file and can be downloaded from \href{https://github.com/jacobmilligan/intro_hd_report}{github}, as part of the source for the finished project, alongside the bitmap resources we'll be using (if you don't have git installed you can just click the 'clone or download' link and download as a zip file). These extra files are important for loading bitmaps, updating the camera position relative to the edge of the map, and drawing a map overview to the screen.

\section{Coding Terrain Generation}

\subsection{Setting Up}

\paragraph{The primary goal of this article is to implement Diamond-Square and must be done prior to any other terrain generation.}\mbox{}
First, download and install the \href{http://www.freepascal.org/download.var}{latest version of FPC} (Free Pascal Compiler) and a Pascal SwinGame template from the \href{http://swingame.com/index.php/downloads.html}{SwinGame Website} (see each websites installation section for instructions on how to do this). Once this is complete, copy your downloaded SwinGame template to wherever you normally store your code, i.e. \mintinline{bash}{/Users/Jacob/Dev/Repos/}. All of the programming will take place in the \mintinline{bash}{/src/} folder and whenever the game needs to be built and run, type the command \mintinline{bash}{./build.sh && ./run.sh} (drop the \mintinline{bash}{./} on Windows machines). Rename the \mintinline{pascal}{GameMain.pas} file to something a bit more descriptive, such as \mintinline[breaklines]{pascal}{ProceduralGeneration.pas} and open it up in your favourite text editor.

The first thing we need to do is to replace the code in the stock \mintinline{pascal}{Main()} procedure with the following:

\begin{minted}[bgcolor=darkgray,style=native]{pascal}
procedure Main();
var
  map: MapData;
begin
  DiamondSquare(map, 100, 20);
  PrintMapToConsole(map);
end;
\end{minted}

Before we render anything to a graphics window, we should first implement our algorithm and ensure that it functions correctly by printing it to the console, both procedures that will be called from \mintinline{pascal}{Main()}. We've also declared a new \mintinline{pascal}{MapData} variable which we'll be creating soon.

\vspace{1mm}

Next, create a new file in the \mintinline{bash}{/src/} directory called \mintinline{pascal}{Terrain.pas}, open it up and write a new Unit file skeleton:

\begin{mdframed}[topline=false,bottomline=false,backgroundcolor=darkgray]
\begin{minted}[style=native,tabsize=2,breaklines]{pascal}
unit Terrain;

interface
	uses SwinGame;

	type
		// Valid tile types for building maps with. Used as a terrain flag for different logic.
		TileType = (Water, Sand, Dirt, Grass, MediumGrass, HighGrass, SnowyGrass, Mountain);

		// Represents a feature on top of a tile that can have a bitmap, collision, and be interactive
		FeatureType = (NoFeature, Tree);

		// Represents a tile on the map - has a terrain flag, elevation and bitmap
		Tile = record
			flag: TileType; // Terrain type
			feature: FeatureType; // Type of feature if any
			collidable: Boolean; // Tile uses collision detection
			elevation: Integer; // The tiles elevation - zero represents sealevel.
			bmp: Bitmap; // Tiles base bitmap
			featureBmp: Bitmap; // If has feature, its bitmap
			hasBmp: Boolean;
		end;

		// Array used to hold a tilemap
		TileGrid = array of array of Tile;

		// Main representation of the current map. Holds a tile grid, alongside data related to size, smoothness, seed values.
		MapData = record
			tiles: TileGrid; // All of the tiles on a map
			player: Sprite;
			playerX, playerY: Integer; // Tile-based coordinates
			size, seed, tilesize, playerIndicator: Integer; // Map settings
		end;

	// Fills a MapData's TileGrid with generated heightmap data using the Diamond-Square fractal generation algorithm
	// This heightmap data gets used later on to generate terrain realistically
	procedure DiamondSquare(var map: MapData; maxHeight, smoothness: Integer);

	// Uses elevation values generated by DiamondSquare to assign appropriate bitmaps and randomly generate trees
	procedure GenerateTerrain(var map: MapData);

implementation

	procedure DiamondSquare(var map: MapData; maxHeight, smoothness: Integer);
	begin
		//code
	end;

	procedure GenerateTerrain(var map: MapData);
	begin
		//code
	end;

end.
\end{minted}
\end{mdframed}

\paragraph{That's a lot of code, so let's step through it.}\mbox{}

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
unit Terrain;

interface
	uses SwinGame;

	type

		//
		//	Valid tile types for building maps with.
		//	Used as a terrain flag for different logic.
		//
		TileType = (Water, Sand, Dirt, Grass, MediumGrass, HighGrass, SnowyGrass, Mountain);

		//
		//	Represents a feature on top of a tile that can have a bitmap,
		//	collision, and be interactive
		//
		FeatureType = (NoFeature, Tree);
\end{minted}

First, we create a new \mintinline{pascal}{unit} file named \mintinline{pascal}{Terrain}. A \mintinline{pascal}{unit} file has two sections of code:

\begin{itemize}

\item
The \mintinline{pascal}{interface} where all types are declared alongside \textbf{forward-declared} functions and procedures. This is the part of the \mintinline{pascal}{unit} file that other units and the main program will actually see.

\item
The  \mintinline{pascal}{implementation} section where the body of each function and procedure is actually defined.

\end{itemize}

Each unit and program can make use of the data structures, functions, and procedures created in other units via the \mintinline{pascal}{uses <UnitName>} syntax.

In the \mintinline{pascal}{type} section of the unit, we declare two enumeration types.- \mintinline{pascal}{TileType} \& \mintinline{pascal}{FeatureType}. These will be used by our \mintinline{pascal}{GenerateTerrain()} procedure and the \mintinline{pascal}{MapUtils.pas unit} file to determine how to treat different tiles. Of note is the \mintinline{pascal}{FeatureType enumeration} which at the moment can only be either a Tree or nothing. Generally speaking, If we only wanted to represent Trees in the game world, we would be better off using a \mintinline{pascal}{hasTree Boolean} variable but the reason we've used an \mintinline{pascal}{enumeration} is to future-proof our program; if we wanted to later on add logs or rocks to the game we would only need to add a new element to \mintinline{pascal}{FeatureType} and alter the terrain generation code.
\vspace{5mm}
\begin{mdframed}[backgroundcolor=darkgray]
\begin{minted}[style=native,tabsize=2]{pascal}
//
//	Represents a tile on the map - has a terrain flag,
//	elevation and bitmap
//
Tile = record
	// terrain type
	flag: TileType;

	// type of feature if any
	feature: FeatureType;

	// uses collision detection
	collidable: Boolean;

	//
	//	Represents the tiles elevation - zero represents sea
	//	level.
	//
	elevation: Integer;

	// tiles base bitmap
	bmp: Bitmap;

	hasBmp: Boolean;

	// bitmap for whatever feature is on top of the tiles
	featureBmp: Bitmap;
end;

//
//	Array used to hold a tilemap
//
TileGrid = array of array of Tile;

//
//	Main representation of the current map. Holds a tile grid, alongside
//	data related to size, smoothness, seed values.
//
MapData = record
	tiles: TileGrid;
	player: Sprite;
	playerX, playerY: Integer;
	size, seed, tilesize, playerIndicator: Integer;
end;
\end{minted}
\end{mdframed}

\paragraph{Here, we declare our most important records and types.} The \mintinline{pascal}{Tile record} is what represents a single element of our tile grid and contains a \mintinline{pascal}{TileType} \mintinline{pascal}{flag}, a \mintinline{pascal}{FeatureType}, a \mintinline{pascal}{Boolean} variable \mintinline{pascal}{collidable} to communicate that the particular tile is subject to collision detection, the tiles \mintinline{pascal}{elevation Integer} value, its attached base tile \mintinline{pascal}{Bitmap} and its feature \mintinline{pascal}{Bitmap} (in this case either a Tree or an invisible bitmap) to render alongside a \mintinline{pascal}{hasBmp Boolean} value used to stop our drawing procedures from trying to draw a non-existent bitmap and crash the game. We've also declared a new \mintinline{pascal}{open array of dynamic Tile arrays} to function as our tile grid. As 2D arrays are essentially just an array in which each of its elements is just another array of elements of a specified type, we've used the syntax \mintinline{pascal}{array of array of Tile} to declare this type.

\paragraph{Finally, we declare our \mintinline{pascal}{MapData} type.} This \mintinline{pascal}{record} will hold our tile grid, the players \mintinline{pascal}{Sprite} variable (A data type from the SwinGame library), the size of the map, the size of each tile, it's seed or starting value, and an indicator used by the \mintinline{pascal}{MapUtils.pas DrawMapCartography() procedure} to locate where the player is relative to the drawn tile map. Important to note is the \mintinline{pascal}{playerX} \& \mintinline{pascal}{playerY} variables as these aren't the players position in pixel coordinates (there will be a total of $275952697344$ pixels on the final map, way too large a number to even fit in a \mintinline{pascal}{LongWord} type), they are the players current pixel position translated to 2D array index equivalents - these variables will be used to calculate simple collision detection later on. Lastly, we forward declare our two terrain generation procedures.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2]{pascal}
//
//	Fills a MapData's TileGrid with generated heightmap data
//	using the Diamond-Square fractal generation algorithm
//	This heightmap data gets used later on to generate terrain realistically
//
procedure DiamondSquare(var map: MapData; maxHeight, smoothness: Integer);

//
//	Uses elevation values generated by DiamondSquare to assign appropriate
//	bitmaps and randomly generate trees
//
procedure GenerateTerrain(var map: MapData);
\end{minted}

\pagebreak

\subsection{Implementing Diamond-Square}

\paragraph{Moving onto the \mintinline{pascal}{implementation} section, we can now build our terrain generation algorithms.} Starting with \mintinline{pascal}{DiamondSquare}. The basic pseudocode for the algorithm looks something like this:

\begin{algorithm}[H]
\setstretch{1.35}
\caption{The Diamond-Square algorithm}
\begin{algorithmic}
\Procedure{DiamondSquare}{$map,\ maxHeight,\ smoothness$}
	\State Initialize the four corners of the map with a seed value
	\State $nextStep \gets \frac{Length(tileGrid)}{2}$

	\While{$nextStep > 0$}
		\ForAll{$midPoints$ of each square in the grid}  \Comment{Do square step}
			\State $midPoint \gets$ Average four corners $+ \ (Random(maxHeight) \times smoothness)$
		\EndFor
		\ForAll{Diamonds in the map} \Comment{We now have diamonds, do diamond step}
			\State $pointCount \gets 0$
			\ForAll{$point$ in a diamond}
				\If{Within boundaries of the tile grid}
					\State $midPoint \gets midPoint \ + \ point$
					\State $pointCount\gets pointCount+1$
				\EndIf
			\EndFor
			\State $midPoint \gets \frac{midPoint}{pointCount} + (Random(maxHeight) \times smoothness$)
		\EndFor
		\State $nextStep \gets \frac{nextStep}{2}$ \Comment{Smaller diamonds and squares}
		\State $smoothness \gets \frac{smoothness}{2}$ \Comment{Higher elevations have less radical difference in height}
	\EndWhile

\EndProcedure
\end{algorithmic}
\end{algorithm}

Writing pseudocode can often be a good idea for breaking down a complex problem, making the underlying process seem a lot simpler. Consequentially, we now have a good abstraction to reference when implementing the algorithm, so let's start on building it into our source code.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2]{pascal}
implementation

	procedure DiamondSquare(var map: MapData; maxHeight, smoothness: Integer);
	var
		x, y: Integer;
		midpointVal: Double;
		nextStep, cornerCount: Integer;
	begin
		x := 0;
		y := 0;
		midpointVal := 0;
		nextStep := Round(Length(map.tiles) / 2 ); // Center of the tile grid

		// Seed upper-left corner extremely low elevation to force it to
		// start with water
		map.tiles[x, y].elevation := -1500;
\end{minted}

Initially, we declare the x \& y variables to track our iterations through the heightmap generation process, then the \mintinline{pascal}{midpointVal Double} which we will use to calculate the current midpoint value (average plus a random value) at both the diamond and square steps. The \mintinline{pascal}{nextStep} variable is an important one and will control which tile in the grid we're analysing at any given moment and will be made smaller at each iteration until it equals 0, at which point the algorithm is finished. This is initially assigned the centre point of each axis in the tile grid, at first being multiplied by two to get the four corners of the map, and at each iteration will be used to determine the location of a given point in a diamond or a square. Finally, we 'seed' the top-left corner of the map with an elevation of $-1500$ to ensure that the map will always have some ocean as its starting point which will help achieve our goal of producing a continent-like map.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2]{pascal}
// Initialize four corners of map with the same value as above
while x < Length(map.tiles) do
begin
	while y < Length(map.tiles) do
	begin
		map.tiles[x, y].elevation := map.tiles[0, 0].elevation;
		y += 2 * nextStep;
	end;

	x += 2 * nextStep;
	y := 0;
end;
\end{minted}

We then iterate all four corners of the map, stepping the entire length of the map at a time, and assign each corner the same elevation value as the top-left corner. Something that you may notice is that we aren't using the more obvious \mintinline{pascal}{for..do loop} to iterate the 2D tile grid. This is due to a quirk that's relatively unique to Pascal and some Pascal-derived languages in that a \mintinline{pascal}{for..do loop} can only increment the control variable by $1$ at a time. However we need to increment $2 \cdot nextStep$ (currently half the size of the map) at each iteration to get to the next corner of the map, therefore we'll be using \mintinline{pascal}{while..do loops}.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2]{pascal}
x := 0;
y := 0;

while nextStep > 0 do
begin
	midpointVal := 0;
\end{minted}

Here begins the core of the generation process, essentially we want to continue to iterate the process into smaller and smaller sizes until \mintinline{pascal}{nextStep} is smaller than the size of the tile grid. Inside this loop we start with the \textbf{square step}:

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
x := nextStep;
while x < Length(map.tiles) do
begin

	y := nextStep;
	while y < Length(map.tiles) do
	begin

		//
		// Sum surrounding points equidistant from the midpoint
		// in a square shape
		//
		midpointVal := map.tiles[x - nextStep, y - nextStep].elevation
					 + map.tiles[x - nextStep, y + nextStep].elevation
					 + map.tiles[x + nextStep, y - nextStep].elevation
					 + map.tiles[x + nextStep, y + nextStep].elevation;

		// Set midpoint to the average + Random value and multiply by smoothing factor
		map.tiles[x, y].elevation := Round( (midpointVal / 4) + (Random(maxHeight) * smoothness) );
		y += 2 * nextStep;
	end;

	x += 2 * nextStep;
	y := 0;
end;
\end{minted}

Here, we're scanning the tile grid for squares and their corners of the current iteration size, as in \hyperref[fig:graph]{Example 2, step 5}. \mintinline{pascal}{midpointVal} is assigned the sum of the four corners in a square surrounding the current midpoint, \mintinline[breaklines]{pascal}{map.tiles[x, y]}, then we assign the midpoints elevation value the average of the points plus a random value with a maximum possible height of our passed-in \mintinline{pascal}{maxHeight} variable \mintinline[breaklines]{pascal}{Random(maxHeight)}. Each time we complete the elevation assignment statement, also seen in a similar fashion the diamond step, we ensure we multiply the random value by the given \mintinline[breaklines]{pascal}{smoothness} parameter to allow the terrain to smooth out as the elevations become higher and the calculated map spaces become smaller to allow for less radical and unrealistic changes. \textbf{Very importantly, because we aren't using \ \mintinline{pascal}{for..do loops}, note that we're manually resetting both \mintinline{pascal}{x} \& \mintinline{pascal}{y}}, if you forget to do this before each iteration you may lose your mind. Let's move onto the diamond step.

\newgeometry{margin=0.5in}

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
// Diamond step. Points in a diamond shape around a given midpoint. Checks if they're within the bounds of the map
x := 0;
while x < Length(map.tiles) do
begin

	y := nextStep * ( 1 - Round(x / nextStep) mod 2);
	while y < Length(map.tiles) do
	begin
		midpointVal := 0;
		cornerCount := 0;

		// Sum the surrounding points equidistant from the current midpoint in a diamond shape. Ensures that each point is within the bounds of the map
		if ( y - nextStep >= 0 ) then
		begin
			midpointVal += map.tiles[x, y - nextStep].elevation;
			cornerCount += 1;
		end;
		if ( x + nextStep < Length(map.tiles) ) then
		begin
			midpointVal += map.tiles[x + nextStep, y].elevation;
			cornerCount += 1;
		end;
		if ( y + nextStep < Length(map.tiles) ) then
		begin
			midpointVal += map.tiles[x, y + nextStep].elevation;
			cornerCount += 1;
		end;
		if ( x - nextStep >= 0 ) then
		begin
			midpointVal += map.tiles[x - nextStep, y].elevation;
			cornerCount += 1;
		end;

		// If at least one corner is within the map bounds, calculate average plus a random amount less than the map height.
		if cornerCount > 0 then
		begin
			// Set midpoint to the average of corner amt + Random value and multiply by smoothing factor
			map.tiles[x, y].elevation := Round( (midpointVal / cornerCount) + Random(maxHeight) * smoothness );
		end;

		y += 2 * nextStep;
	end;

	x += nextStep;
end;
\end{minted}

\restoregeometry

\paragraph{The diamond step is a little more complicated.} The reason for this is that we need to do extra checking to ensure that a given point in the diamond is within the maps boundary to avoid both calculation errors and a \mintinline{pascal}{EAccessViolation} error for accessing a non-existent memory address.

Once again we have two, nested \mintinline{pascal}{while..do loops} with their control variables manually reset and incremented at the before and at the end of each iteration. Before entering each inner loop, rather than assigning \mintinline[breaklines]{pascal}{y := nextStep} as in the square step, we assign \mintinline{pascal}{y} a seemingly confusing new value which will be equal to the next point in the diamond. Why is this the case? Well, given the formula, where $s=$ \mintinline{pascal}{nextStep}:

\begin{equation}
y=s \cdot (1 - \left[\frac{x}{s} \ mod \ 2\right]
\end{equation}

If, at the current iteration in the process, $x=0$ \& $s=3$ which is coincidentally where $x$ will be at the beginning of the diamond step and what \mintinline{pascal}{nextStep} will be assigned in the first iteration of a $5 \times 5$ grid, we would get:

\begin{equation}
\begin{split}
y&=3 \cdot (1 - \left[\frac{0}{3} \ mod \ 2\right]) \\
&=3 \cdot (1 - \left[0 \ mod \ 2\right]) \\
&=3 \cdot (1 - [0]) \\
&=3
\end{split}
\end{equation}

\mintinline{pascal}{y} is now the two elements from the right point of the diamond and will be skipped this iteration then, given
\\ \mintinline{pascal}{x += nextStep} in the next iteration, \mintinline{pascal}{x} will now be $3$, so if we plug that into the formula again, we get:

\begin{equation}
\begin{split}
y&=3 \cdot (1 - \left[\frac{3}{3} \ mod \ 2\right]) \\
&=3 \cdot (1 - \left[1 \ mod \ 2\right]) \\
&=3 \cdot (1 - [1]) \\
&=3 \cdot 0 \\
&=0
\end{split}
\end{equation}

So now \mintinline{pascal}{y} is set to the top point of the left-most diamond and so on. This simple formula allows us to iterate four points of a diamond without having to resort to using numerous \mintinline{pascal}{if} statements.

In the body of the inner loop, we then check each point surrounding the mid-point to see if it's inside the bounds of the map. If it is, we increment \mintinline{pascal}{cornerCount} once. Then, after checking all points we assign the mid-point the average of all surrounding points within the bounds of the map plus a random value limited to our \mintinline{pascal}{maxHeight} variable multiplied by the current smoothness factor. Finally, we increase the value of \mintinline{pascal}{y} in the inner loop by the length of the current diamond to get the lower point and iterate until all diamonds in the current loop are calculated.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
		nextStep := Round(nextStep / 2); // Make the next space smaller

		//
		//	Increase smoothness for every iteration, allowing
		//	less difference in height the more iterations that are completed
		//
		smoothness := Round(smoothness / 2);
	end;
end;
\end{minted}

\paragraph{We're almost done.} At the end of the current diamond-square iteration, we make the size of our diamonds and squares smaller by halving \mintinline{pascal}{nextStep} alongside halving \mintinline{pascal}{smoothness} so that higher elevations have a less radical difference in height. Changing our smoothness value is what creates a realistic gradient in heights and a more visually pleasing result.

\subsection{Testing}

\paragraph{The most complex and difficult part is out of the way.}But before we do anything else, it must be tested. If we were to wait until we had all of our drawing, collision, and update procedures built, we would be well into finishing our program before we'd even made sure the core algorithm behind it works. To do this, we can go back to our main program file, \mintinline{pascal}{ProceduralGeneration.pas}, and implement the \mintinline[breaklines]{pascal}{PrintMapToConsole()} and \mintinline[breaklines]{pascal}{CreateMap()} procedures/functions we wrote in \mintinline{pascal}{Main()}.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
// Prints all of the elevation data in a tilemap to the console.
// Don't use for maps larger than 16 x 16 or it will be bigger than the console window
procedure PrintMapToConsole(constref map: MapData);
var
	x, y: Integer;
begin
	for x := 0 to High(map.tiles) do
  	begin
  		for y := 0 to High(map.tiles) do
	  	begin
  			Write(map.tiles[x, y].elevation, ' ');
	  	end;
  		WriteLn();
	  end;
end;
\end{minted}

The code for this procedure is fairly self-explanatory - we iterate the 2D array and write all \mintinline[breaklines]{pascal}{y} values without appending a newline to simulate a row, then at the end of each \mintinline[breaklines]{pascal}{x} iteration, write a newline to the console to simulate a column. Then, we move onto \mintinline[breaklines]{pascal}{CreateMap()}.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
//
//  Initializes a new tile grid and then generates a new map using DiamondSquare().
//  The new map can be random or based off a given seed
//
function CreateMap(size: Integer; random: Boolean; seed: Integer = 0): MapData;
var
  i, j: Integer;
begin
  result.tilesize := 32;
  result.size := size;
  result.player := CreateSprite('player', BitmapNamed('player')); // We'll use this later

  // Setup seed
  if random then
  begin
    Randomize;
  end
  else
  begin
    RandSeed := seed;
  end;

  // Initialize Tile Grid
  SetGridLength(result.tiles, size);
  // Generate Heightmap
  DiamondSquare(result, 100, 20);
end;
\end{minted}

\mintinline[breaklines]{pascal}{CreateMap()} takes three parameters - a value to determine the map size, a \mintinline[breaklines]{pascal}{Boolean} variable to determine if we should generate a random map or one from a pre-determined seed value, and the actual seed value if any exist, using the \mintinline[breaklines]{pascal}{<variable>: <type> = <value>} syntax to declare a default parameter that doesn't have to necessarily be passed as an argument when calling the procedure. We first assign a tilesize, size, and player sprite for our \mintinline[breaklines]{pascal}{MapData result} variable. Then, if \mintinline[breaklines]{pascal}{random} is true we call the \mintinline[breaklines]{pascal}{Randomize procedure} which initializes Pascals internal random number generator with a new, unique seed to base all random generation off. Much like our \emph{seed} value used to base all of our Diamond-Square calculations off, the Pascal \mintinline[breaklines]{pascal}{Random()} function, a deterministic \emph{pseudo-random} number generation algorithm, itself requires a seed value, generated by the exact time on the computers system clock down to nanoseconds, to base its calculations off. If \mintinline[breaklines]{pascal}{random} is false, we then assign our seed value to the Pascal \mintinline[breaklines]{pascal}{RandSeed} variable, which sets \mintinline[breaklines]{pascal}{Random()}'s seed value manually rather than using the system clock via \mintinline[breaklines]{pascal}{Randomize}. We then call \mintinline[breaklines]{pascal}{SetGridLength()} (listed below) to initialize our 2D array and pass our map into \mintinline[breaklines]{pascal}{DiamondSquare()} to get assigned a heightmap.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
//	Initializes the 2D map grid with the given size and sets the default
//	values for each tile
procedure SetGridLength(var tiles: TileGrid; size: Integer);
var
	column: Integer;
	x, y: Integer;
begin

	// Set all of the column sizes to the right length
	for column := 0 to size do
	begin
		SetLength(tiles, column, size);
	end;

	// Iterate map and setup default values for all tiles
	for x := 0 to High(tiles) do
	begin
		for y := 0 to High(tiles) do
		begin
			// Setup default values
			tiles[x, y].elevation := 0;
			tiles[x, y].collidable := false;
			tiles[x, y].feature := NoFeature;
			tiles[x, y].hasBmp := false;
		end;
	end;
end;
\end{minted}

Now all of our core procedures and functions are defined, we can test out our \mintinline[breaklines]{pascal}{DiamondSquare() procedure} by calling \mintinline[breaklines]{pascal}{CreateMap(9, 100, 20)} from \mintinline[breaklines]{pascal}{Main()}; we want to pass in a very small size value to \mintinline[breaklines]{pascal}{CreateMap()} otherwise we won't be able to see all of the printed elevation numbers in the console. Note that we're passing in a size of $9$ rather than $8$; this is because, as previously discussed, \mintinline[breaklines]{pascal}{DiamondSquare()} only works for maps of size $2^{n}+1$ and 9 is $2^{3}+1$. Run \mintinline[breaklines]{bash}{./build.sh && ./run.sh} in the console from the root project folder and we can see the result:

\begin{figure}[H]
	\centering
	\renewcommand{\figurename}{Example}
	\includegraphics[width=0.9\linewidth,trim=4 4 4 4,clip]{printtoconsole.png}
	\caption{The heightmap printed to the console}
\end{figure}

Although it may look fairly unimpressive now, we can at least verify that our algorithm works and produces pseudo-random values distributed across nice, smooth gradients. Let's move onto our \mintinline[breaklines]{pascal}{GenerateTerrain()} procedure to actually begin implementing a graphical representation of our map.

\subsection{Generating Terrain and Features}

\paragraph{In order to graphically represent terrain, we need to assign Bitmaps and \mintinline[breaklines]{pascal}{FeatureTypes}.} This will be defined in our \mintinline[breaklines]{pascal}{GenerateTerrain() procedure}. This step in terrain generation is less complex than \mintinline[breaklines]{pascal}{DiamondSquare()} \emph{at the present}; it's possible, and encouraged, to extend this this procedure after finishing the program and, for many procedurally generated games, \mintinline[breaklines]{pascal}{DiamondSquare()} is just the beginning with the most complex algorithms belonging to the terrain generation procedures and functions. However, our focus is on generating a base map to get started with procedural generation. If you are interested, a visit to the Procedural Content Generation Wiki \parencite{pcg} is highly recommend and browsing the many articles listed there will give a good jumping off point for many varied procedural processes.

Before we begin building the \mintinline[breaklines]{pascal}{GenerateTerrain() procedure} lets outline exactly how we want it to work by using pseudocode to abstract the algorithmic problem.

\begin{algorithm}[H]
\setstretch{1.35}
\caption{Procedure to Generate Terrain}
\begin{algorithmic}
\Procedure{GenerateTerrain}{$map$}
	\For{$x \gets 0$ \ To \ $High(tiles)$} \Comment{Generate tile Bitmaps}
		\For{$y \gets 0$ \ To \ $High(tiles)$}
			\State Assign a different Bitmap to $tiles[x, y]$ for different $elevation$ ranges
			\If{$tiles[x,y]$ $elevation$ value is $< 0$}
				\State $tiles[x, y] \gets$ Dark Water Bitmap
			\Else
				\State $tiles[x, y] \gets$ Mountain Bitmap \Comment{$elevation > 1499$}
			\EndIf

			\If{$Random() > 0.9$ \textbf{and} $tiles[x,y]$ is not a Water tile}
				\State $tiles[x, y]'s \ FeatureType \gets$ A tree appropriate for the current tile type
			\EndIf
		\EndFor
	\EndFor
\EndProcedure
\end{algorithmic}
\end{algorithm}

Essentially all we need to do is iterate over our previously generated 2D heightmap and assign each tile a Bitmap based on its elevation value. At certain elevations we may choose to apply different processes later on for more complex generation, but all we're doing at the moment is assigning the right tile Bitmap to the right elevation value. The second part of the process is generating appropriate tree Bitmaps based on a very random process; it's highly encouraged to extend this and explore \label{forestalgo}forest generation algorithms that work by creating seeds, sunlight, and maturation processes (see \cite{forests}) but for the moment we're going to apply a process to achieve a semi-procedural result.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
// Generates the terrain type for each tile based off its elevation value
procedure GenerateTerrain(var map: MapData);
var
	x, y: Integer;
begin
	// Iterate all tiles and change their bitmap and data depending on their
	// pre-generated altitude
	for x := 0 to High(map.tiles) do
	begin
		for y := 0 to High(map.tiles) do
		begin

			// Setup the tiles
			case map.tiles[x, y].elevation of
				0..199: SetTile(map.tiles[x, y], Water, 'water', true);
				200..299: SetTile(map.tiles[x, y], Sand, 'sand', false);
				300..399: SetTile(map.tiles[x, y], Grass, 'grass', false);
				400..599: SetTile(map.tiles[x, y], MediumGrass, 'dark grass', false);
				600..799: SetTile(map.tiles[x, y], HighGrass, 'darkest grass', false);
				800..999: if Random(10) > 6 then
							// Generate patchy snow at mid-to-high elevations
							SetTile(map.tiles[x, y], SnowyGrass, 'snowy grass', false)
						  else
							SetTile(map.tiles[x, y], HighGrass, 'darkest grass', false);
				1000..1499: SetTile(map.tiles[x, y], SnowyGrass, 'snowy grass', false);
\end{minted}

First, we delare our \mintinline[breaklines]{pascal}{GenerateTerrain()} procedure and begin iterating the 2D tile grid. We then define several elevation ranges inside a \mintinline[breaklines]{pascal}{case} statement for which we assign the current tiles Bitmap using \mintinline[breaklines]{pascal}{SetTile()} (which we'll implement soon) - lower elevations get water, while higher elevations get snowy grass. At elevation ranges of $800-999$ we randomly assign either snow or grass to simulate patchy snow as the terrain transitions to higher altitudes.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
				else
					// Only generate dark water if elevation is low enough
					// otherwise, every other value, which will be higher than 1499, should
					// become mountains
					if map.tiles[x, y].elevation  < 0 then
						SetTile(map.tiles[x, y], Water, 'dark water', true)
					else
						SetTile(map.tiles[x, y], Mountain, 'mountain', true)
			end;

			// Generates trees randomly. Feel free to extend this by making your own
			// procedural tree generation algorithm to make beautiful forests!
			if ( Random() > 0.9 ) and ( map.tiles[x, y].flag <> Water ) then
			begin
				SetFeature(map.tiles[x, y], Tree, true);
			end;

		end;
	end;
end;
\end{minted}

If the current tiles elevation value is outside the specified ranges we fall to the \mintinline[breaklines]{pascal}{else} block and assign elevations lower than $0$ deep water tiles and anything not less than $0$ will be higher than $1499$ so we assign it a mountain tile. Finally, we randomly set the tiles' \mintinline[breaklines]{pascal}{featureBmp} to either a tree or nothing depending on both a random value and as long as the current tile isn't a water tile as trees don't generally grow in the ocean.

\paragraph{You will have noticed both \mintinline[breaklines]{pascal}{SetTile()} \& \mintinline[breaklines]{pascal}{SetFeature()} procedures.} These handle assigning default values to tiles and assigning the right tree for the right \mintinline[breaklines]{pascal}{TileType} respectively. Let's quickly code them up:

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
// Sets a tiles values to specified. Anything with collidable set to true
// won't be able to be walked over by the player
procedure SetTile(var newTile: Tile; flag: TileType; bmp: String; collidable: Boolean);
begin
	newTile.flag := flag;
	newTile.bmp := BitmapNamed(bmp);
	newTile.collidable := collidable;
	newTile.hasBmp := true;
end;
\end{minted}

\mintinline[breaklines]{pascal}{SetTile()} assigns all of the specified values alongside any required default values for a given tile which saves us the hassle of rewriting this code each time we want to setup a tile.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
//
//	Sets up a new feature on a given tile. At the moment we only have trees
//	as valid features but it's really easy for you to add more features!
//	Why not try adding rocks, logs or even treasure?
//
procedure SetFeature(var tile: Tile; feature: FeatureType; collidable: Boolean);
begin
	tile.feature := feature;
	tile.collidable := collidable;

	if feature = Tree then
	begin
		case tile.flag of
			Water: tile.featureBmp := BitmapNamed('hidden');
			Sand: tile.featureBmp := BitmapNamed('palm tree');
			Dirt: tile.featureBmp := BitmapNamed('tree');
			Grass: tile.featureBmp := BitmapNamed('tree');
			MediumGrass: tile.featureBmp := BitmapNamed('pine tree');
			HighGrass: tile.featureBmp := BitmapNamed('pine tree');
			SnowyGrass: tile.featureBmp := BitmapNamed('snowy tree');
			Mountain: tile.featureBmp := BitmapNamed('hidden');
		end;
	end;
end;
\end{minted}

\mintinline[breaklines]{pascal}{SetFeature()} is fairly self explanatory - it uses a \mintinline[breaklines]{pascal}{case} statement on the tile parameter's \mintinline[breaklines]{pascal}{TileType} to determine which tree bitmap to load up. Notice, a feature can also be collidable (you shouldn't be able to walk through trees) and, using the syntax \mintinline[breaklines]{pascal}{if feature = <FeatureType> then}, we can specify different logic for different types of features, such as \mintinline[breaklines]{pascal}{if feature = Rock then //rock logic}, once again future-proofing our program for extensibility.

Return to \mintinline[breaklines]{pascal}{CreateMap()} and add in a call to \mintinline[breaklines]{pascal}{GenerateTerrain(result)}. However, if you run the program now, it won't work. In order to draw the map to the screen, we need to both load our resources up and implement a \mintinline[breaklines]{pascal}{DrawMap()} procedure.

\section{Drawing, Input, and Collision}

\subsection{Drawing the map}

Before we can draw anything to the screen we need to open a SwinGame graphics window and define a main game loop, so let's go to our \mintinline[breaklines]{pascal}{Main()} procedure and edit it to look like this:

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
procedure Main();
var
  map: MapData;
begin

  LoadResources();

  // Open a SwinGame graphics window for drawing to
  OpenGraphicsWindow('Procedural Map Generation', 800, 600);

  map := CreateMap(513, true);

  repeat
    ProcessEvents();

    ClearScreen(ColorBlack);

    UpdateCamera(map);
    DrawMap(map);
    DrawSprite(map.player);

    RefreshScreen(60);
  until WindowCloseRequested();
end;
\end{minted}

We define our main game loop to \mintinline[breaklines]{pascal}{repeat..until WindowCloseRequested()}, which happens when the user clicks to exit the window. Both \mintinline[breaklines]{pascal}{LoadResources()} \& \mintinline[breaklines]{pascal}{UpdateCamera()} are from the \mintinline[breaklines]{pascal}{MapUtils.pas unit} file and do exactly what the say they do, loading resources and making sure the camera is always centred on our player. We call \mintinline[breaklines]{pascal}{DrawMap()} to draw our map to the screen which is the procedure we'll be implementing soon, and the SwinGame API's \mintinline[breaklines]{pascal}{DrawSprite()} procedure to draw the player to the screen. More SwinGame procedures, \mintinline[breaklines]{pascal}{ClearScreen()} \& \mintinline[breaklines]{pascal}{RefreshScreen()} are called every iteration alongside \mintinline[breaklines]{pascal}{ProcessEvents()} for input handling.

\paragraph{Before we implement \mintinline[breaklines]{pascal}{DrawMap()}, we need to create a function to check if a particular element is inside the bounds of the tile grid.} \

\begin{mdframed}[backgroundcolor=darkgray]
\begin{minted}[style=native,tabsize=2,breaklines]{pascal}
//
//	Determines whether a given point is inside the tilemap or not
//
function IsInMap(constref map: MapData; x, y: Integer): Boolean;
begin
	result := false;

	// Check map bounds. As every map is (2^n)+1 in size, the bounds
	// stop at High()-1 which will be a number equal to 2^n.
	if (x > 0) and (x < High(map.tiles) - 1) and (y > 0) and (y < High(map.tiles) - 1) then
	begin
		result := true;
	end;
end;
\end{minted}
\end{mdframed}

\paragraph{Once we've implemented \mintinline[breaklines]{pascal}{IsInMap()} we can move onto \mintinline[breaklines]{pascal}{DrawMap()}:}
\
\vspace{0.5cm}

\begin{mdframed}[backgroundcolor=darkgray]
\begin{minted}[style=native,tabsize=2,breaklines]{pascal}
//
//	Draws the current map data to the screen but only within the bounds of
//	the current Camera view.
//
procedure DrawMap(constref map: MapData);
var
	x, y: Integer;
	newView: TileView;
begin
	// Get a new tile view to see what should be drawn
	newView := CreateTileView(map);

	// Iterate only tiles in the tile map that correspond to a
	// visible tile
	for x := newView.x to newView.right do
  	begin
	  	for y := newView.y to newView.bottom do
	  	begin

	  		if IsInMap(map, x, y) and map.tiles[x, y].hasBmp then
	  		begin
	  			// Draw the tile
	  			DrawBitmap(map.tiles[x, y].bmp, x * map.tilesize, y * map.tilesize);
	  			// Draw a tree or no feature
					DrawBitmap(map.tiles[x, y].featureBmp, x * map.tilesize, y * map.tilesize);
	  		end;

	  	end;
  	end;
end;
\end{minted}
\end{mdframed}

\

In our \mintinline[breaklines]{pascal}{DrawMap()} procedure we create a new \mintinline[breaklines]{pascal}{TileView} record, this is from the \mintinline[breaklines]{bash}{MapUtils.pas} unit file and is used to translate the current camera view in pixels ($800 \times 600$ in the case of our game) into tile grid coordiantes ($25 \times 19$). We then make use of the \mintinline[breaklines]{pascal}{x, right, y, bottom record} members it returns to draw whatever tiles are currently within the cameras view to the screen through a nested \mintinline[breaklines]{pascal}{for..do} loop, also checking that the tile is inside the map bounds and has an assigned bitmap before drawing it. The reason we use a \mintinline[breaklines]{pascal}{TileView} record to only draw what's visible rather than the entire map is that, if we were drawing $512 \cdot 512 = 262,144$ tiles to the screen at each game loop, the program would run extremely slow.
\subsection{Handling Input \& Collision}
\paragraph{Now that we've implemented our drawing procedure, we can move onto input and collision detection:}\mbox{}

 \vspace{0.2cm}
 \
 \begin{mdframed}[backgroundcolor=darkgray]
 \begin{minted}[style=native,tabsize=2,breaklines]{pascal}
procedure HandleInput(var map: MapData);
var
	newX, newY: Integer;
begin

	// Used to determine if they should be allowed to move in a given direction
	newX := map.playerX;
	newY := map.playerY;

	// Change values depending on direction
	if KeyDown(UpKey) then
	begin
		newY -= 1;
	end;
	if KeyDown(RightKey) then
	begin
		newX += 1;
	end;
	if KeyDown(DownKey) then
	begin
		newY += 1;
	end;
	if KeyDown(LeftKey) then
	begin
		newX -= 1;
	end;
 \end{minted}
 \end{mdframed}
 \

Here, we pass in our \mintinline[breaklines]{pascal}{MapData} variable and save the players current tile-based (as against pixel-based) $x$ and $y$ values into the \mintinline[breaklines]{pascal}{newX} \& \mintinline[breaklines]{pascal}{newY} variables as we'll be altering this data later. Next we use the SwinGame procedure \mintinline[breaklines]{pascal}{KeyDown()} to move the players $x$ \& $y$ values in the correct direction. Here, we are essentially \emph{predicting} what the players' coordinates will be on the next iteration of the game loop before we \emph{actually} move the player, which is why we aren't assigning these new coordinates to the player directly, rather saving the predicted coordinates in order to do some collision detection:

 \begin{mdframed}[backgroundcolor=darkgray]
 \begin{minted}[style=native,tabsize=2,breaklines]{pascal}
	//	If either newX or newY are outside the map bounds or are a collidable tile, reset
	//	the players position and don't move them
	if (newX <= 0) or (newX >= High(map.tiles) - 1) or (map.tiles[newX, newY].collidable) then
	begin
		newX := map.playerX;
	end;
	if (newY <= 0) or (newY >= High(map.tiles) - 1) or (map.tiles[newX, newY].collidable) then
	begin
		newY := map.playerY;
	end;

	// Assign the new values to the player
	map.playerY := newY;
	map.playerX := newX;

	// Move the player according to world coordinates rather than tile
	// coordinates by multiplying their tile coordinates by the tilesize
	SpriteSetY(map.player, map.playerY * map.tilesize);
	SpriteSetX(map.player, map.playerX * map.tilesize);

end;
 \end{minted}
 \end{mdframed}

\

In the above \mintinline[breaklines]{pascal}{if..then} statements we check to see if the players \emph{predicted} $x$ or $y$ values are outside the maps boundary or are on top of a collidable tile. If either of these conditions are true, then we reset either one or both axis' by assigning \mintinline[breaklines]{pascal}{newX or newY} the players original coordinate values. Finally, we assign the new tile-based coordinates, whether they've changed or not, to the player directly and call the SwinGame \mintinline[breaklines]{pascal}{SpriteSetX()} \& \mintinline[breaklines]{pascal}{SpriteSetY()} procedures to actually change the players in-game pixel-based coordinates by multiplying the tile values by the maps \mintinline[breaklines]{pascal}{tilesize} value.

\clearpage

\subsection{Finishing Up}

\paragraph{We're almost done.} However, first we need to append our \mintinline[breaklines]{pascal}{Main()} \& \mintinline[breaklines]{pascal}{CreateMap()} procedures with some new code to allow our player to spawn in a correct location and to handle input.
\
Edit \mintinline[breaklines]{pascal}{CreateMap()} with the following code:
\
\vspace{0.5cm}

\begin{adjustwidth}{-1cm}{-1cm}
\begin{mdframed}[backgroundcolor=darkgray]
\begin{minted}[style=native,tabsize=2,breaklines]{pascal}
//	Initializes a new tile grid and then generates a new map using DiamondSquare().
//	The new map can be random or based off a given seed
function CreateMap(size: Integer; random: Boolean; seed: Integer = 0): MapData;
var
	i, j: Integer;
	spawnFound: Boolean;
begin
	result.tilesize := 32;
	result.size := size;
	result.player := CreateSprite('player', BitmapNamed('player'));

	// Setup seed
	if random then
	begin
		Randomize;
	end
	else
	begin
		RandSeed := seed;
	end;

	// Initialize Tile Grid
	SetGridLength(result.tiles, size);
	// Generate Heightmap
	DiamondSquare(result, 100, 20);

	GenerateTerrain(result);

	//	Search for the first sand tile without a feature on it, thus spawning the player on a beach
	spawnFound := false;
	for i := 0 to High(result.tiles) do
	begin
		if spawnFound then
			break;

		for j := 0 to High(result.tiles) do
		begin
			if spawnFound then
				break;

			// Search for a sand tile to spawn the player on
			if (i > 1) and (result.tiles[i, j].flag = Sand) and (result.tiles[i, j].feature = NoFeature) then
			begin
				SpriteSetX(result.player, i * 32);
				SpriteSetY(result.player, j * 32);
				result.playerX := i;
				result.playerY := j;
				spawnFound := true;
			end;
		end;
	end;

	// Recursively call self with new random value if spawn not found
	if not spawnFound then
	begin
		CreateMap(size, true, seed);
	end;
end;
\end{minted}
\end{mdframed}
\end{adjustwidth}

\paragraph{The primary addition here, is to search for the players spawn point.} We create a nested \mintinline[breaklines]{pascal}{for..do} loop to iterate the tile grid and search for the first sand tile, then assign the players position accordingly; a very simple way to find a spawn point but effective enough for our program. The most interesting section of code in this procedure is also the shortest:

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
// Recursively call self with new random value if spawn not found
if not spawnFound then
begin
	CreateMap(size, true, seed);
end;
\end{minted}

If the specified seed or random seed value produces a map with only water tiles then we use \textbf{recursion} to call \mintinline[breaklines]{pascal}{CreateMap()} itself again but with a new random seed. Recursion is an interesting concept in programming and occurs when part of a procedure or function calls itself and runs the same block of code again, but often with new parameters; the return value of which follows the chain of recursion back to the start, itself being recursive by definition \parencite{recursion}. Recursive procedures for the most part are interchangeable with loops, and are often more easily followed that way, but some procedures such as \mintinline[breaklines]{pascal}{CreateMap()}, lend themselves so naturally to the concept of recursion that it only makes real sense to define them as such. This means that the \mintinline[breaklines]{pascal}{CreateMap()} procedure will keep calling itself until it produces a valid map with a valid spawn point.

\paragraph{Finally, edit \mintinline[breaklines]{pascal}{Main()} so that it calls the new procedures.} We'll also add a little bit of code to delay the players movement so that \mintinline[breaklines]{pascal}{HandleInput()} is only called once every 3 frames rather than every frame, otherwise the movement speed of the player would be too fast.

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
procedure Main();
const
	MOVE_INTERVAL = 4;
var
	map: MapData;
	moveDelay: Integer;
begin

	LoadResources();

  OpenGraphicsWindow('Procedural Map Generation', 800, 600);

	map := CreateMap(513, true);

	moveDelay := 0;
	repeat
		ProcessEvents();

		ClearScreen(ColorBlack);

		// Only moves the player at specific intervals so as to
		// limit from running super fast
		moveDelay += 1;
		if moveDelay > MOVE_INTERVAL then
		begin
			HandleInput(map);
			moveDelay := 0;
		end;

		UpdateCamera(map);
		DrawMap(map);
		DrawSprite(map.player);
\end{minted}

Furthermore, we'll also check if the player has typed escape and then draw a small map overview to the screen until escape is typed again. This way the player is able to find their position on the map at any given moment:

\begin{minted}[bgcolor=darkgray,style=native,tabsize=2,breaklines]{pascal}
		// Create map drawing loop to show player where they are
		if KeyTyped(EscapeKey) then
		begin
			ProcessEvents();
			repeat
				ProcessEvents();
				DrawMapCartography(map); // Draw the map to screen
			until KeyTyped(EscapeKey) or WindowCloseRequested();
		end;

		RefreshScreen(60);
	until WindowCloseRequested();
end;
\end{minted}

Note, that we've also called \mintinline[breaklines]{pascal}{CreateMap()} with a size value of $2^{9}+1 = 513$ in order to generate our map without hitting any errors. If you want to generate maps of different sizes, just remember they must be of size
\\
$2^{n}+1$.

\paragraph{Finally, build and run the game and you should have a fully procedurally generated world able to be navigated by the player.}\mbox{}

\begin{figure}[H]
	\centering
	\includegraphics[width=0.9\linewidth,trim=4 4 4 4,clip]{finalresult.png}
	\renewcommand{\figurename}{Example}
	\caption{The final in-game result}
\end{figure}

\begin{figure}[H]
	\centering
	\includegraphics[width=0.9\linewidth,trim=4 4 4 4,clip]{finalmap.png}
	\renewcommand{\figurename}{Example}
	\caption{The accompanying map overview}
\end{figure}

\clearpage

\section{Extending \& Investigating Deeper}
Our goal at the beginning of this article was to implement a realistic heightmap generation algorithm and use it to procedurally create terrain representations and features on a 2D tile-based map. Ultimately, this goal has been reached while also touching on other complex problems such as collision detection and efficient drawing procedures alongside making use of an external API in the form of SwinGame.
\par
However, the resulting program is just a starting point and has been built in such a way that it can be extended as needed. This is highly encouraged and there a plethora of algorithms and processes to be discovered and implemented in your program:
\begin{itemize}
\item
Carving out rivers using a combination of Hart, Nilsson, and Raphaels A* Pathfinding algorithm \parencite{astar} to find the shortest path to the ocean or a lake using elevation as the path cost, in combination with Diamond-Square to distort the river paths realistically.
\item
Producing dense forests via a combination of procedures previously mentioned \hyperref[forestalgo]{here} and various cellular automata processes
\item
Generating flora and fauna such as flowers and rabbits by simulating seeds, growth, breeding, and lifespan factors. The possibilities here, in particular, are truly enormous and are where many of the most interesting problems lie.
\item
Finally, as in the previously mentioned Dwarf Fortress, it's possible to apply narrative generation algorithms to carve out of entire centuries of history and culture, literally creating entire databases of generated lore for a game.
\end{itemize}

As demonstrated in this article, it's completely within the grasp of the reader to create realistic terrain that's unique and interesting without having to create all of the content manually. The possibilities are endless and only limited by your imagination.

\printbibliography

\appendix
\setcounter{secnumdepth}{0}
\section{Source Code \& Repository}
The complete finished project directory and all source code files referenced in this article can be downloaded from the repository listed on \href{https://github.com/jacobmilligan/intro_hd_report}{github.com} by cloning or forking the project via git, or simple navigating to the 'clone or download' button and downloading as a .zip file. The repository includes all resource files alongside \\ \mintinline[breaklines]{pascal}{MapUtils.pas}. If you have find any issues or bugs in the code provided, feel free to open a new issue on the repository page or fork and contribute any fixes or additions.
\end{document}


\mainsection{SCALE Dummies Guide}
There are a lot of types defined here, and to exploit the most
from the system you need to (kind of) understand how the MPC
engine works under-the-hood. As most people will not be able
to do that we here provide a quick dummy guide to get the most
performance out of the system.
In this section we are mainly talking about your programs, and
not system tuning for an application. The latter topic is far
more of a black-art alas.

\subsection{Integer Types}
There two {\em basic} clear integer types $\ints$ and \verb|ClearModp|.
The former represent $64$-bit integers and the latter integers
modulo $p$, for the prime you have chosen. These work at
roughly machine speed, bar any overhead due to the VM.
There is an {\em advanced} clear integer types \verb|Integer<K>|
which holds an integer in $\Z$ as a \verb|ClearModp| but with the
`soft' gaurantee that the integer lies in $\Zk$.
On the secret side these are duplicated by the \verb|SecretI64|,
\verb|SecretModp| and \verb|SecretInteger<K>| types.

Note the secret operations are {\em always} more expensive than
the clear operations, and that \verb|SecretI64| operations are
generally more expensive than \verb|SecretModp| operations.
The \verb|SecretInteger<K>| type is more costly than a
\verb|SecretModp| type, as it has to worry about size issues.
Conversion between \verb|SecretModp| and  \verb|SecretI64| types
are expensive, thus best avoided if possible.
Conversion betwen \verb|SecretModp| and  \verb|SecretInteger<K>|
types if for free, as it is assumed the programmer knows
the conversion will be `valid'.

But there seems to be more arithmetic operations for \verb|SecretI64|
than for \verb|SecretModp|. For example, you cannot compare
two \verb|SecretModp| values (after all integers modulo $p$ have
no notion of `size', so mathematically this makes no sense).

However, in MPC algorithms we often use \verb|SecretModp| values
to hold integers (i.e. elements of $\Z$) and compute on them
whilst keeping a mental note of how big they are. This means
we can perform operations by keeping in the \verb|SecretModp|
domain, without needing to convert to \verb|SecretI64| values.

\begin{lstlisting}
   let a = SecretModp::from(10);
   let b = SecretModp::from(20);

   let c = a*b;
   let d = a+b;

   // Suppose we now want to "compare" c and d.
   // We know the max size is 9 bits (c is 200,
   // which is at least 9 bits in signed representation)
   let ci : SecretInteger<9> = SecretInteger::from(c);
   let di : SecretInteger<9> = SecretInteger::from(d);
   let compare = ci.lt(di);
\end{lstlisting}
The above is {\em much} faster than mapping \verb|c|
and \verb|d| over to the \verb|SecretI64| domain and doing
the comparison there.
Obviously the above code is a bit fake, as you know what the
values are, but you can see the idea.

\subsection{Floating Point Types}
In general \verb|ClearIEEE| should be your preferred clear floating
point type, as it provides almost machine level performance.
The preferred secret floating point type is \verb|SecretFixed<K,F>|
as it is much faster. However, it only provides fixed point arithmetic.
If true floating point is required then  \verb|SecretFloat<V,P>|
is better, but it can result in programs which take ages to compile.
For faster compilation, but slower programs, use  \verb|SecretIEEE|

\subsection{Bits}
There is a \verb|SecretBit| type. Due to some current limitations
of the intermediate \verb|wasm| representation there is a lot of
conversions between \verb|SecretBit| types and \verb|SecretModp|
types under the hood. This results in slower programs than are really
necessary. Once \verb|wasm| has been extended to cope with more than
four basic register types this restriction will be removed.