Managing the Game



Now the script contains a solid basic frame/structure around which we will add code to actually handle the game. This means sequence randomization algorythms, key validations, point system logic, etc. Let's start by the game initialization routine.


The simon:Initialize() function previously added will be called right before a new game is requested by the player. Our main goal in this function is to reset all of our game handling variables previously created and intialize random logic. In the world of computers, generating random is not an easy thing to achieve. Let's be realistic, it's impossible to recreate exactly what random is by definition. On the other hand, we can generate something so huge in terms of quantity of possibilities, that statistically and humanly speaking, we can call this random. Lua's pseudo-random engine works the same way as in C++. In fact, "behind the scene", Lua uses the C++ pseudo-random engine. This engine works with seeds to generate "random" sequences of numbers. A seed is a number which will be used to generate "random" numbers. In other words, two sequences using the same seed will be identical. To avoid this problem, many scripts/programs use the system's current time as the random seed, which pratically makes it impossible for the user to get or even remember having the same sequence. Here is how the simon:Initialize() function should look like:



-- Initialize the game
function simon:Initialize()
    -- Initalize variables
    simon:SetScore(0)
    GameState = true
    UserSequenceCount = 0
    SequenceCount = 0
    MainSequence = {}

    -- Initialize random engine
    math.randomseed(os.time())
    math.random()
    math.random()
    math.random()
end


In this previous code example, math.random() function is called three times because under some operating systems (at least in Windows 2k®) the first random number you get is not really "randomized". (Source taken from the lua-users wiki website) To get better pseudo-random numbers, we just pop some random numbers before using them for real. The other lines of code in that previous example initialize the variables previously declared in the step 2 of this tutorial. Next, let's add some code in the simon:AddSequence(Sequence) function. The goal of this function is to append a new item to the sequence that the player is going to have to reproduce later. To do so, we will increment by 1 the global variable SequenceCount and we will "randomize" a number from 1 to 4. That generated number is going to represent the light to turn on in the sequence. Here is how the function should looks like:



-- Add one more part to the game's sequence
function simon:AddSequence()
    SequenceCount = SequenceCount + 1
    MainSequence[SequenceCount] = math.random(4)
end


Next, we will fill the simon:PlaySequence(Sequence) function. The main goal of this function is to play the sequence previously built via calls to the Simon® game's engine exported functions. In this function, we should parse the sequence table item by item and turn on the light that this item is worth. Let's be more specific:



-- Play the game's sequence
function simon:PlaySequence(Sequence)
    local v = nil
    local i = nil

    -- Lock controls from user to make sure no conflicts happened while palying sequence
    simon.LockControls()

    -- Play all sequence
    repeat
        simon.SetLight(SIMON_NONE)
        Sleep(300)
        i, v = next(Sequence, i)
        simon.SetLight(v)

        if i ~= nil then
            Sleep(500)
        end
    until i == nil

    simon.UnlockControls()
    simon.SetLight(SIMON_NONE)
end


The two local variables v and i are going to be use to retrieve the result of our calls to the next() function. The next() function is used to retrieve the next element in a lua table by specifiying the actual table and the index of the current element as parameters. The simon.LockControls() and simon.UnlockControls() functions are exported from the game's engine and their main goal is to lock/unlock the controls from the player to avoid any conflict in the code. In the previous example of code, the calls to the simon.LockControls() and simon.UnlockControls() functions will be made before and after the loop that is actually displaying the sequence to the player. Also, in the code sample the "repeat...until" statement was used to allow the code to enter in the loop for the first iteration everytime it has to but any other loop syntax would have been a proper use as well. The first chunk in the loop is a call to the simon.SetLight() function using SIMON_NONE as first and only parameter. This instruction will turn off all the lights in the game because we want to make sure that for each item no other light but the one of the current item will be on. Next, we have a Sleep() call of 300 miliseconds as the argument. This call, unlike the one in step 2 of this tutorial, has the same effect on the computer but is more used as a "pause" feature than a CPU "slower" kind of feature. With what has been clarify so far, you should be able to understand the remaining lines that I didn't detailed.

To finalize this step we will add some code to the simon:OnButtonClick(ButtonIndex) function. This function will be called by the Simon® game's engine every time the player pushes one of the four buttons in the game. Our main goal in that function is to validate the pushed button and start managing points for an eventual victory. To do so, the functions simon.GetScore() and simon.SetScore() will be used. View the simplicity of this function and the advancement in the tutorial, this function will not be explained in details. Just remember what we've dicussed so far in the turorial:



-- Event handler called by simon.dll when any of the colored buttons are clicked
function simon:OnButtonClick(ButtonIndex)
    local Result = 0
    UserSequenceCount = UserSequenceCount + 1

    if MainSequence[UserSequenceCount] == ButtonIndex then
        simon.SetScore(simon.GetScore() + 10)
        Result = 1
    end

    return Result
end


In the next step of this tutorial, we will discuss more about controling the game in the main loop and linking the functions from the C/C++/Delphi dll file.



www.luaedit.org
© Copyright 2004-2005 LuaEdit
Bind a Dll to LuaEdit (Tutorial)