In this section I present some of the coding projects I’ve delved in lately, just for fun.

 

Hunt the Wumpus

Wumpus Cover

Download Wumpus: CPlusPlus

This is a clone of the classic BASIC game Hunt the Wumpus, made in C++ during the course of a single day.

The player needs to hunt the Wumpus, a mythical creature that is located somewhere in the underground maze. To  hunt it, the player needs to know where it is and shoot it with a spear. However, the player only has one spear and there are bottomless pits. The only clues available to the player are a Stench when the Wumpus is nearby, a Breeze when there’s a pit nearby and Glitter when there’s gold in the room.

I did this project as a way of reinforcing my C++ skills, using a project that dealt with player input, multidimensional arrays, pointer usage, classes and gameplay loops. Below is the code for the entire project.

[tab name=”Main.cpp”]

#include "GameManager.h"
#include <iostream>

int main()
{
	GameManager gameManager;
	gameManager.BuildMaze();
	gameManager.Play();
	gameManager.DisplayEndMessage();
	gameManager.DeleteMaze();

	return 0;
}

[/tab]
[tab name=”GameManager.h”]

#pragma once

#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H

#include "Player.h"
#include "Wumpus.h"

#include <string>

class GameManager
{
public:
	GameManager();
	void BuildMaze();
	void DeleteMaze();
	void Play();
	void DisplayEndMessage();

private:
	Player player;
	Wumpus wumpus;
	char **maze;
	char **mazeToPrint;
	bool gameOver;

	void ClearScreen();
	void PrintMaze();
	void UpdateMazeToPrint();
	std::string IsPlayerAlive();
	void CheckSenses();
	void CheckSenseSquare(int x, int y, std::string direction);
	void PrintInstructions();
	bool ProcessPlayerInput();
	bool CheckSpearProgress();
};

#endif

[/tab]
[tab name=”GameManager.cpp”]

#include "GameManager.h"

#include <string>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define ROWS 5
#define COLUMNS 5
#define NUM_ROOM_GOLD 10
#define NUM_ROOM_PIT 5
#define GOLD_SCORE 100
#define ROOM_EMPTY ' '
#define ROOM_GOLD 'g'
#define ROOM_PIT 'p'
#define ROOM_WALL 'w'
#define ALIVE_MESSAGE_WUMPUS "wumpus"
#define ALIVE_MESSAGE_PIT "pit"
#define ALIVE_MESSAGE_ALIVE "alive"
#define FORWARD "FORWARD"
#define TURN_LEFT "TURN LEFT"
#define TURN_RIGHT "TURN RIGHT"
#define GRAB "GRAB"
#define SHOOT "SHOOT"
#define CLIMB "CLIMB"
#define QUIT "QUIT"

using std::string;
using std::getline;

GameManager::GameManager()
{
	gameOver = false;
}

// Builds the game maze and sets the starting position of the player and wumpus.
void GameManager::BuildMaze()
{
	maze = new char*[ROWS];
	mazeToPrint = new char*[ROWS];
	for(int i=0; i < COLUMNS; i++)
	{
		maze[i] = new char[COLUMNS];
		mazeToPrint[i] = new char[COLUMNS];
	}

	//By default, every room is blank.
	for (int i=0; i < ROWS; i++)
	{
		for (int j=0; j < COLUMNS; j++)
		{
			maze[i][j] = ROOM_EMPTY;
			mazeToPrint[i][j] = ROOM_EMPTY;
		}
	}

	//We select the rooms that will have gold and pits.
	for(int i = 0; i < NUM_ROOM_GOLD; i++)
	{
		int goldX = std::rand() % ROWS;
		int goldY = std::rand() % COLUMNS;

		while(maze[goldX][goldY] != ROOM_EMPTY)
		{
			goldX = std::rand() % ROWS;
			goldY = std::rand() % COLUMNS;
		}

		maze[goldX][goldY] = ROOM_GOLD;
	}

	for(int i = 0; i < NUM_ROOM_PIT; i++)
	{
		int pitX = std::rand() % ROWS;
		int pitY = std::rand() % COLUMNS;

		while(maze[pitX][pitY] != ROOM_EMPTY)
		{
			pitX = std::rand() % ROWS;
			pitY = std::rand() % COLUMNS;
		}

		maze[pitX][pitY] = ROOM_PIT;
	}

	//Sets the starting position of the player and the wumpus
	srand ( (unsigned int) time(NULL));
	int posX = std::rand() % ROWS;
	int posY = std::rand() % COLUMNS;

	while(maze[posX][posY] != ROOM_EMPTY)
	{
		posX = std::rand() % ROWS;
		posY = std::rand() % COLUMNS;
	}

	player.SetPosition(posX, posY);
	player.startX = posX;
	player.startY = posY;

	//Wumpus position
	do
	{
		posX = std::rand() % ROWS;
		posY = std::rand() % COLUMNS;
	}while( ( (posX == player.x) && (posY == player.y) ) || (maze[posX][posY] != ROOM_EMPTY ) );

	wumpus.SetPosition(posX, posY);

	//printf("Player is at position %d, %d\n", player.x, player.y);
	//printf("Wumpus is at position %d, %d\n", wumpus.x, wumpus.y);

}

//Deletes the maze so there's no memory leak. Only called at the end of the game.
void GameManager::DeleteMaze()
{
	for(int i =0; i < COLUMNS; i++)
	{
		delete [] maze[i];
		delete [] mazeToPrint[i];
	}
	delete [] maze;
	delete [] mazeToPrint;
}

//Core game loop.
void GameManager::Play()
{
	int auxInt;
	string aliveMessage;

	//Welcome message.
	printf("Welcome to the dangerous world of Wumpus!\n");
	printf("Will you be able to kill the Wumpus... or will the Wumpus kill YOU?\n\n\n");
	printf("Please press ENTER to continue...\n");
	auxInt = std::getchar();

	do
	{
		ClearScreen();
		PrintMaze();

		aliveMessage = IsPlayerAlive();

		printf("\n\n\n\n");

		if(aliveMessage == ALIVE_MESSAGE_WUMPUS)
		{
			printf ("Game Over, man! Game over! You have been eaten by the Wumpus!!\n\n");
			gameOver = true;
		}

		if (aliveMessage == ALIVE_MESSAGE_PIT)
		{
			printf("You have fallen into a bottomless pit. Hooray!\n\n");
			gameOver = true;
		}

		if(aliveMessage == ALIVE_MESSAGE_ALIVE)
		{
			CheckSenses();
			PrintInstructions();
			gameOver = CheckSpearProgress();
			if(!gameOver)
			{
				gameOver = ProcessPlayerInput();
			}
		}

	}while(!gameOver);

	printf("Press ENTER to continue.\n");
	std::getline(std::cin, aliveMessage);

}

void GameManager::ClearScreen()
{
	for(int i=0; i < 10; i++)
	{
		printf("\n\n\n\n\n\n\n\n\n\n");
	}
}

//Prints the maze. Used in the Play method.
void GameManager::PrintMaze()
{
	UpdateMazeToPrint();

	for(int i=0; i < ROWS; i++)
	{
		printf(" - - - - - \n");
		printf("|%c|%c|%c|%c|%c|\n", mazeToPrint[i][0], mazeToPrint[i][1], mazeToPrint[i][2], mazeToPrint[i][3], mazeToPrint[i][4]);
	}

	printf(" - - - - - \n");
}

//Updates the maze that is shown to the player.
void GameManager::UpdateMazeToPrint()
{
	for(int i =0; i < ROWS; i++)
	{
		for(int j=0; j < COLUMNS; j++)
		{
			#pragma region PLAYER CELL
			if(player.x == i && player.y == j)
			{
				if(player.orientation == Player::UP)
				{
					mazeToPrint[i][j] = '^';
				}
				else if (player.orientation == Player::DOWN)
				{
					mazeToPrint[i][j] = 'v';
				}
				else if (player.orientation == Player::LEFT)
				{
					mazeToPrint[i][j] = '<';
				}
				else if(player.orientation == Player::RIGHT)
				{
					mazeToPrint[i][j] = '>';
				}
				else
				{
					mazeToPrint[i][j] = ' ';
				}
			}
#pragma endregion

			//Discomment this section if you want to see the Wumpus in the map.
			/*
			#pragma region WUMPUS CELL
			else if (wumpus.x == i && wumpus.y == j)
			{
				mazeToPrint[i][j] = 'W';
			}
			#pragma endregion
			*/

			#pragma region REGULAR CELL
			else
			{
				//Discomment the following line if you want to see the pits and gold rooms.
				//mazeToPrint[i][j] = maze[i][j];
				mazeToPrint[i][j] = ROOM_EMPTY;
			}
			#pragma endregion
		}
	}
}

//Checks if the player is alive. This means that it's not in the same position as the Wumpus or a pit.
string GameManager::IsPlayerAlive()
{
	if(player.x == wumpus.x && player.y == wumpus.y)
	{
		return ALIVE_MESSAGE_WUMPUS;
	}

	else if (maze[player.x][player.y] == ROOM_PIT)
	{
		return ALIVE_MESSAGE_PIT;
	}
	else
	{
		return ALIVE_MESSAGE_ALIVE;
	}
}

//Checks adjacent squares to find danger, wumpus, etc.
void GameManager::CheckSenses()
{
	//We first check if there is gold in the same room
	if(maze[player.x][player.y] == ROOM_GOLD)
	{
		printf("You feel Glitter in the room.\n");
	}

	bool canUp = false, canDown = false, canLeft = false, canRight = false;

	//First, we need to find the adjacent squares.
	int xUp = player.x - 1, yUp = player.y,
		xDown = player.x + 1, yDown = player.y,
		xLeft = player.x, yLeft = player.y - 1,
		xRight = player.x, yRight = player.y + 1;

	#pragma region Check Adjacent Square Validity
	if(xUp >= 0 && xUp < COLUMNS)
	{
		canUp = true;
	}

	if(xDown >= 0 && xDown < COLUMNS)
	{
		canDown = true;
	}

	if(yLeft >=0 && yLeft < ROWS)
	{
		canLeft = true;
	}

	if(yRight >=0 && yRight < ROWS)
	{
		canRight = true;
	}
	#pragma endregion

	#pragma region Check Adjacent Square Senses
	if(canUp)
	{
		CheckSenseSquare(xUp, yUp, "North");
	}
	if(canDown)
	{
		CheckSenseSquare(xDown, yDown, "South");
	}
	if(canLeft)
	{
		CheckSenseSquare(xLeft, yLeft, "West");
	}
	if(canRight)
	{
		CheckSenseSquare(xRight, yRight, "East");
	}
	#pragma endregion

}

//Check the individual square of the labyrinth to see if we communicate the player the senses.
void GameManager::CheckSenseSquare(int x, int y, string direction)
{
	if (x == wumpus.x && y == wumpus.y)
	{
		printf("You feel Stench. The wumpus is nearby!\n");
		return;
	}
	if(maze[x][y] == ROOM_EMPTY)
	{
		return;
	}
	if(maze[x][y] == ROOM_PIT)
	{
		printf("You feel a Breeze. You are near a pit!\n");
		return;
	}
	if(maze[x][y] == ROOM_WALL)
	{
		printf("You feel a Bump. There's a wall nearby...\n");
	}
}

//Print the instructions with the available verbs.
void GameManager::PrintInstructions()
{
	printf("\n\n");
	printf("Select one of the valid commands and press ENTER to continue.\n");
	printf("VALID COMMANDS:\n");

	printf("%s\n", FORWARD);
	printf("%s\n", TURN_LEFT);
	printf("%s\n", TURN_RIGHT);
	printf("%s\n", GRAB);
	printf("%s\n", SHOOT);
	printf("%s\n", CLIMB);
	printf("%s\n", QUIT);

	printf("\n\n");
	printf("Your score: %d\n", player.score);
	printf("Number of spears: %d\n\n", player.numSpears);
	printf("Type your command:\n");
}

//Gets the player input and performs the desired action.
//Returns true if the player decides to escape the cave or types QUIT. Returns false otherwise.
bool GameManager::ProcessPlayerInput()
{
	//Get player input
	string playerInput;
	std::getline(std::cin, playerInput);

	#pragma region FORWARD
	//srtcasecmp(playerInput.c_str(), FORWARD);
	if(_stricmp(playerInput.c_str(), FORWARD) == 0)
	{
		//We determine the next square to move on, depending on the orientation of the player.
		int nextX, nextY;
		if(player.orientation == Player::UP)
		{
			nextX = player.x - 1;
			nextY = player.y;
		}
		else if(player.orientation == Player::DOWN)
		{
			nextX = player.x + 1;
			nextY = player.y;
		}
		else if(player.orientation == Player::LEFT)
		{
			nextX = player.x;
			nextY = player.y - 1;
		}
		else if(player.orientation = Player::RIGHT)
		{
			nextX = player.x;
			nextY = player.y + 1;
		}

		if(nextX >=0 && nextX < COLUMNS && nextY >= 0 && nextY < ROWS)
		{
			player.SetPosition(nextX, nextY);
			printf("You move forward\n");
		}
		else
		{
			printf("You cannot move in this direction\n");
		}
	}
	#pragma endregion

	#pragma region TURN_LEFT
	else if(_stricmp(playerInput.c_str(), TURN_LEFT) == 0)
	{
		if(player.orientation == Player::UP)
		{
			player.orientation = Player::LEFT;
			printf("You are now facing LEFT\n");
		}
		else if (player.orientation == Player::DOWN)
		{
			player.orientation = Player::RIGHT;
			printf("You are now facing RIGHT\n");
		}
		else if(player.orientation == Player::LEFT)
		{
			player.orientation = Player::DOWN;
			printf("You are now facing DOWN\n");
		}
		else if(player.orientation == Player::RIGHT)
		{
			player.orientation = Player::UP;
			printf("You are now facing UP\n");
		}
	}
	#pragma endregion

	#pragma region TURN_RIGHT
	else if(_stricmp(playerInput.c_str(), TURN_RIGHT) == 0)
	{
		if(player.orientation == Player::UP)
		{
			player.orientation = Player::RIGHT;
			printf("You are now facing RIGHT\n");
		}
		else if (player.orientation == Player::DOWN)
		{
			player.orientation = Player::LEFT;
			printf("You are now facing LEFT\n");
		}
		else if(player.orientation == Player::LEFT)
		{
			player.orientation = Player::UP;
			printf("You are now facing UP\n");
		}
		else if(player.orientation == Player::RIGHT)
		{
			player.orientation = Player::DOWN;
			printf("You are now facing DOWN\n");
		}
	}
	#pragma endregion

	#pragma region GRAB
	else if(_stricmp(playerInput.c_str(), GRAB) == 0)
	{
		if(maze[player.x][player.y] == ROOM_GOLD)
		{
			printf("You have grabbed %d gold coins!\n", GOLD_SCORE);
			player.score += GOLD_SCORE;
			maze[player.x][player.y] = ROOM_EMPTY;
		}
		else
		{
			printf("You did not find any gold in this room.\n");
		}
	}
	#pragma endregion

	#pragma region SHOOT
	else if (_stricmp(playerInput.c_str(), SHOOT) == 0)
	{
		if(player.numSpears == 1)
		{
			printf("You fire your spear!\n");
			player.numSpears = 0;
			player.spear.isActive = true;
			player.spear.hasBeenUsed = true;
			player.spear.SetPosition(player.x, player.y);

			if(player.orientation == Player::UP)
			{
				player.spear.spearOrientation = Spear::UP;
			}
			else if(player.orientation == Player::DOWN)
			{
				player.spear.spearOrientation = Spear::DOWN;
			}
			else if(player.orientation == Player::LEFT)
			{
				player.spear.spearOrientation = Spear::LEFT;
			}
			else if (player.orientation == Player::RIGHT)
			{
				player.spear.spearOrientation = Spear::RIGHT;
			}
		}

		else
		{
			printf("You don't have any more spears!\n");
		}
	}
	#pragma endregion

	#pragma region CLIMB
	else if(_stricmp(playerInput.c_str(), CLIMB) == 0)
	{
		if(player.startX == player.x && player.startY == player.y)
		{
			printf("You climb out of the cave.\n");
			return true;
		}
		else
		{
			printf("You can only climb out of the cave at your starting position.\n");
		}
	}
	#pragma endregion

	#pragma region QUIT
	else if(_stricmp(playerInput.c_str(), QUIT) == 0)
	{
		printf("I'm sorry to see you go. See ya next time!\n");
		return true;
	}
	#pragma endregion

	#pragma region OTHER
	else
	{
		printf("You cannot do that action.\n");
	}
	#pragma endregion

	printf("Press ENTER to continue\n");
	std::getline(std::cin, playerInput);
	return false;

}

//Checks if the spear is active or not. If affirmative, it moves the spear and sees if it has to eliminate it or not.
//Returns true if we killed the Wumpus. Returns false otherwise.
bool GameManager::CheckSpearProgress()
{
	if(player.spear.isActive)
	{
		int nextX, nextY;

		#pragma region Get Next Position
		if (player.spear.spearOrientation == Spear::UP)
		{
			nextX = player.spear.x - 1;
			nextY = player.spear.y;
		}
		else if (player.spear.spearOrientation == Spear::DOWN)
		{
			nextX = player.spear.x + 1;
			nextY = player.spear.y;
		}
		else if (player.spear.spearOrientation == Spear::LEFT)
		{
			nextX = player.spear.x;
			nextY = player.spear.y - 1;
		}
		else if (player.spear.spearOrientation == Spear::RIGHT)
		{
			nextX = player.spear.x;
			nextY = player.spear.y + 1;
		}
		#pragma endregion

		#pragma region Check Spear State
		if(nextX >=0 && nextX < ROWS && nextY >=0 && nextY < COLUMNS)
		{
			player.spear.SetPosition(nextX, nextY);

			//Check if we have killed the Wumpus.
			if(player.spear.x == wumpus.x && player.spear.y == wumpus.y)
			{
				printf("You hear a SCREAM from somewhere in the cave. The wumpus is dead!\n");
				player.spear.hasBeenUsed = true;
				player.spear.isActive = false;
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			printf("Your spear has collided with a wall and broke!\n");
			player.spear.hasBeenUsed = true;
			player.spear.isActive = false;
			return false;
		}
		#pragma endregion

	}
	else
	{
		return false;
	}
}

//Display the message at the end of the game, telling the player the score.
void GameManager::DisplayEndMessage()
{
	ClearScreen();
	printf("Thank you for playing Wumpus!\n");
	printf("Your total score was %d points.\n", player.score);
	printf("\n\n");

	//So the player presses a key to exit.
	string auxInput;
	printf("Press ENTER to exit.\n");
	std::getline(std::cin, auxInput);
}

[/tab]
[tab name=”Player.h”]

#pragma once

#ifndef PLAYER_H
#define PLAYER_H

#include "Spear.h"

class Player
{
public:
	enum PlayerOrientation {UP, DOWN, LEFT, RIGHT};

	int x, y, score, numSpears, startX, startY;
	PlayerOrientation orientation;
	Spear spear;

	Player();
	void SetPosition (int posX, int posY);
	void AddScore (int scoreToAdd);

};

#endif

[/tab]
[tab name=”Player.cpp”]

#include "Player.h"

Player::Player()
{
	x = 0;
	y = 0;
	score = 0;
	startX = 0;
	startY = 0;
	numSpears = 1;
	orientation = UP;
}

void Player::AddScore(int scoreToAdd)
{
	score += scoreToAdd;
}

void Player::SetPosition(int posX, int posY)
{
	x = posX;
	y = posY;
}

[/tab]
[tab name=”Wumpus.h”]

#pragma once

#ifndef WUMPUS_H
#define WUMPUS_H

class Wumpus
{
public:
	int x,y;

	Wumpus();
	void SetPosition(int posX, int posY);

};
#endif

[/tab]
[tab name=”Wumpus.cpp”]

#include "Wumpus.h"

Wumpus::Wumpus()
{
	x = 0;
	y = 0;
}

void Wumpus::SetPosition(int posX, int posY)
{
	x = posX;
	y = posY;
}

[/tab]
[tab name=”Spear.h”]

#pragma once
#ifndef SPEAR_H
#define SPEAR_H

class Spear
{
public:
	enum SpearOrientation {UP, DOWN, LEFT, RIGHT};
	bool isActive;
	bool hasBeenUsed;
	int x,y;
	SpearOrientation spearOrientation;

	Spear();
	void SetPosition(int posX, int posY);
};

#endif

[/tab]
[tab name=”Spear.cpp”]

#include "Spear.h"

Spear::Spear()
{
	x = 0, y = 0;
	isActive = false, hasBeenUsed = false;
	spearOrientation = UP;
}

void Spear::SetPosition(int posX, int posY)
{
	x = posX;
	y = posY;
}

[/tab]
[end_tabset]

 


Tic-Tac-Lua

Tic-Tac-Lua Cover

Download Tic-Tac-Lua: Lua

This is the classic game Tic-Tac-Toe, done in Lua during a 3-4 hour time period.

In this game, the player needs to place three “X” symbols in a row, while avoiding the computer from doing the same. I did this project as a way of remembering and reinforcing my Lua scripting skills, while using good coding practices and concepts like functions, user input, game loop and multidimensional tables for the game board. Below is the code for the entire project.

[tab name=”Tic-Tac-Lua.lua”]

--Global variables
tblBoard = {}

--Clears the screen so we can print again from scratch.
function ClearScreen()
	os.execute("cls")
end

--Sets up the board so we can add characters into it.
function FillBoard()
	tblBoard [ 1 ] = {" ", " ", " "}
	tblBoard [ 2 ] = {" ", " ", " "}
	tblBoard [ 3 ] = {" ", " ", " "}
end

--Writes the game board on the screen
function WriteBoard()

	-- The line between the lines.
	local sLineSpace = "_|_|_"

	-- Board print loop.
	for v = 1,3,1 do
		print(tblBoard[v][1].."|"..tblBoard[v][2].."|"..tblBoard[v][3])
		if(v < 3) then
			print(sLineSpace)
		end
	end

end

--Gets a valid numeric input from the player. This means, it's a number and with a value between 1 and 3.
function GetValidPlayerInput(position)
	local sPlayerInput = ""
	local nPlayerInput = nil

	--Get a valid numeric input for both row and column.
	while (nPlayerInput == nil) do
		io.write(position, ": ")
		sPlayerInput =  io.read("*line")
		nPlayerInput = tonumber(sPlayerInput)

		if(nPlayerInput == nil) then
			print("The input entered is not a number. Please enter the input again")
		elseif (nPlayerInput < 1 or nPlayerInput > 3) then
			print("The value written is not valid. It has to be a value between 1 and 3. Please try again.")
			nPlayerInput = nil
		end
	end

	return nPlayerInput
end

--Determines if the position is filled or not 
function DetermineValidPosition(row, column)
	if(tblBoard[row][column] == " ") then
		return true
	else
		return false
	end
end

--Checks if the game is over, and if there is a winner.
--[[
1: Player Won
0: No Winner YET
-1: Computer Won
2: Tie
]]
function CheckGameEnd()
	local bPlayerWon = false
	local bComputerWon = false

	--Check the horizontal combinations first
	for i = 1,3,1 do
		local sChar = tblBoard[i][1]
		if( (tblBoard[i][1] == tblBoard[i][2]) and (tblBoard[i][1] == tblBoard[i][3]) ) then
			print("There's a match in row "..i)
			if(sChar == "X") then
				return 1
			elseif (sChar == "O") then
				return -1
			end
		end 
	end

	--Check the vertical combinations now
	for j = 1,3,1 do
		local sChar = tblBoard[1][j]
		if( (tblBoard[1][j] == tblBoard[2][j]) and (tblBoard[1][j] == tblBoard[3][j]) ) then
			print("There's a match in column "..j)
			if(sChar == "X") then
				return 1
			elseif (sChar == "O") then
				return -1
			end
		end
	end

	--Check the diagonal combinations.
	if ( (tblBoard[2][2] == tblBoard[1][1]) and (tblBoard[2][2] == tblBoard[3][3]) ) then
		local sChar = tblBoard[2][2]
		if(sChar == "X") then
			return 1
		elseif (sChar == "O") then
			return -1
		end
	end

	if ( (tblBoard[2][2] == tblBoard[1][3]) and (tblBoard[2][2] == tblBoard[3][1]) ) then
		local sChar = tblBoard[2][2]
		if(sChar == "X") then
			return 1
		elseif (sChar == "O") then
			return -1
		end
	end 

	--If we've gotten to this point, it means that there is no winner. This means we're completely full in positions in the grid,
	-- or there is no winner yet.
	for i=1,3,1 do
		for j=1,3,1 do
			if(tblBoard[i][j] == " ") then
				return 0
			end
		end
	end 

	--This means the board is full and it's a TIE.
	return 2
end

--Core Game Loop
function GameLoop()

	--Local variables needed for the game loop and plant the random number generator seed.
	math.randomseed(os.time())
	local nInputRow = nil
	local nInputColumn = nil
	local bValidPlayerInput = false
	local bIsGameOver = 0
	local nRandomNumber = 0
	local bIsPlayerTurn = true

	while (bIsGameOver == 0) do
		ClearScreen()
		WriteBoard()

		-- Player input section		
		if(bIsPlayerTurn == true) then
			print("\n\n\n\n")
			print("It's the player's turn. Your symbol is X")
			print("Enter the position where you want to insert a symbol:")

			while (bValidPlayerInput == false) do
				nInputRow = GetValidPlayerInput("Row")
				nInputColumn = GetValidPlayerInput("Column")
				bValidPlayerInput = DetermineValidPosition (nInputRow, nInputColumn)

				--Insert the new player value.
				if(bValidPlayerInput == true) then
					print("The position "..nInputRow..","..nInputColumn.." is valid.")
					tblBoard[nInputRow][nInputColumn] = "X"
					bIsGameOver = CheckGameEnd()
					bIsPlayerTurn = false
				else
					print("The position "..nInputRow..","..nInputColumn.." is NOT valid. Please insert a new location.")
				end
			end

			--Computer input section.
			else
				bValidPlayerInput = false

				--Get a random cell
				while(bValidPlayerInput == false) do
					nInputRow = math.random(3)
					nInputColumn = math.random(3)
					bValidPlayerInput = DetermineValidPosition (nInputRow, nInputColumn)
				end

				--Write the value of the chosen computer cell and give control to player.
				tblBoard[nInputRow][nInputColumn] = "O"
				bIsGameOver = CheckGameEnd()
				bIsPlayerTurn = true
				bValidPlayerInput = false
			end
	end

	--End game instructions.
	ClearScreen()
	WriteBoard()

	print("\n\n\n\n")
	if(bIsGameOver == 1) then
		print("Congratulations! You've won Tic-Tac-Lua!")
	elseif(bIsGameOver == -1) then
		print("You've lost Tic-Tac-Lua. Sorry!")
	elseif(bIsGameOver == 2) then
		print("It's a tie!")
	end

	print("\n\n\n")
	print("Thanks a lot for playing Tic-Tac-Lua! Hope you had fun playing this game")

end

--MAIN PROGRAM FLOW
do
	--Welcome screen
	ClearScreen()
	print("Welcome to Tic-Tac-Lua!!")
	print("In this game, you will fight against a vicious AI in a game of wits... Tic-Tac-Lua!")
	print("Press Enter to continue...")
	io.read()

	--Initializes and starts the game proper.
	ClearScreen()
	FillBoard()
	GameLoop()

end

[/tab]
[end_tabset]

Comments are closed, but trackbacks and pingbacks are open.