Tuesday, December 27, 2011

C# Tutorial: Arithmetic Expression Evaluator

In this tutorial I use a simple algorithm that was developed by E. W. Dijkstra in the 1960s. In order to evaluate the expression, the algorithm uses two stacks: one for operands and one for operators. An expression consists of parentheses, operators, and operands (numbers). Proceeding from left to right and taking these entities one at a time, we manipulate the stacks according to four possible cases, as follows:
  • Push operands onto the operand stack.
  • Push operators onto the operator stack.
  • Ignore left parentheses.
  • On encountering a right parenthesis, pop an operator, pop the requisite number of operands, and push onto the operand stack the result of applying that operator to those operands.
After the final right parenthesis has been processed, there is one value on the stack, which is the value of the expression.
For the sake of simplicity I use a ConsoleApplication project. Add the following code to your Main() method:
// You must separate operands and operators by a white space
// Otherwise it won't work
string[] Expr = Console.ReadLine().Split(' ');
// The two stacks: one for operators and the other for operands
Stack<string> ops = new Stack<string>();
Stack<double> vals = new Stack<double>();
// The Algorithm
foreach (string item in Expr)
{
    switch (item)
    {
        // If item is operator then push 
        case "(": break;
        case "+": ops.Push(item); break;
        case "-": ops.Push(item); break;
        case "*": ops.Push(item); break;
        case "/": ops.Push(item); break;
        case "mod": ops.Push(item); break;
        case "sqrt": ops.Push(item); break;
        case "^": ops.Push(item); break;
        case ")":
            {
                // Pop, evaluate and push result if item is ")"
                string op = ops.Pop();
                double val = vals.Pop();
                switch (op)
                {
                    case "+": val += vals.Pop(); break;
                    case "-": val = vals.Pop() - val; break;
                    case "*": val *= vals.Pop(); break;
                    case "/": val = vals.Pop() / val; break;
                    case "mod": val = vals.Pop() % val; break;
                    case "sqrt": val = Math.Sqrt(val); break;
                    case "^": val = Math.Pow(vals.Pop(), val); break;
                }
                vals.Push(val);
            } break;
        // If not operator or "(" then push double value
        default: vals.Push(double.Parse(item)); break;
    }
}
// Finally, show the result
Console.Write(vals.Pop());
// Wait for user input
Console.ReadKey();
Don't forget to add spaces between operands and operators! Also you have to surround your expression with parenthesis.
That's it! You can now try to add some trig functions or whatever you want. You can also choose to parse the string differently without using space as a delimitator.

Bibliography

Robert Sedgewick, Kevin Wayne. Algorithms Fourth Edition. Pearson Education: Boston, 2011.

Wednesday, April 27, 2011

C++ Tutorial: Create a DLL in VC++ 2010/2008

If the tutorial is too fast for you then read the following steps:

1. Start Visual Studio (or C++ Express Edition) -> Create a new Win32 Console Application project -> Application Settings -> Check DLL and Empy Project -> Hit Finish

2. Go to Solution Explorer -> Right Click on Header Files -> Add a new header file -> Declare your stuff (for example: a new class)

// SimpleH.h
namespace nmspace
{
 class myclass
 {
 public:
  static __declspec(dllexport) void Crap();
 };
}

NOTE: The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. They enable you to export and import functions, data, and objects to and from a DLL.

3. Go to Solution Explorer -> Right Click on Source Files -> Add a new cpp file -> Include your header here #include "YourHeader.h" and define your stuff

// SimpleCPP.cpp
#include <iostream>
using namespace std;
#include "SimpleH.h"

namespace nmspace
{
 void myclass::Crap()
 {
  cout << "I'm called within a crappy DLL!";
 }
}

4. Create a new Win32 Console Application project -> Application Settings -> Leave Console application checked and check Empty Project -> Add a new CPP file (for example: main.cpp)

5. Go to your DLL Project folder and copy the Header file (SimpleH.h), the Object Library File (SimpleDLL.lib) and the DLL itself (SimpleDLL.dll)! Paste these files into your new project folder (where main.cpp is located)

6. Include the Header file (SimpleH.h) to your new project -> Go to Solution Explorer -> Right Click on the Project name (NOT THE SOLUTION) -> References

7. Configuration Properties -> Linker -> Input -> Additional Dependencies -> Add the .lib file (SimpleDLL.lib) -> Hit OK -> HIT APPLY and then OK!

8. In main.cpp call the function from the DLL created -> Start the application

// main.cpp
#include "SimpleH.h"
#include <iostream>
using namespace std;
using namespace nmspace;

int main()
{
 myclass::Crap();
 system("PAUSE");
}

9. Go to you project folder -> Debug folder (The first Debug folder) -> Copy the DLL there -> Start the application -> And you're done!

10. If you found this confusing then watch the video tutorial!

Saturday, April 23, 2011

SAMP Scripting Tutorial: Slap N' Slay

Here is the code

#include <a_samp>

#define RED 0xD20000FF
#define WHITE 0xFFFFFFFF

public OnFilterScriptInit()
{
 print("\n--------------------------------------");
 print(" Slap N' Slay by TheDarkJoker94");
 print("--------------------------------------\n");
 return 1;
}

// The strtok function
strtok(const string[], &index)
{
 new length = strlen(string);
 while ((index < length) && (string[index] <= ' '))
 {
  index++;
 }

 new offset = index;
 new result[20];
 while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
 {
  result[index - offset] = string[index];
  index++;
 }
 result[index - offset] = EOS;
 return result;
}

// The Slap function
Slap(victimid, victimhp, adminid)
{
 new Float: health;
 GetPlayerHealth(victimid, health); // Get victim's health
 health = health - victimhp; // Calculate new health (victimhp is the ammount of HP you want to take from the victim)
 SetPlayerHealth(victimid, health);
 new name[64], output[128];
 GetPlayerName(adminid, name, 64); // Get slapper's name
 format(output, 128, "You have been slapped by %s! [-%d]", name, victimhp);
 SendClientMessage(victimid, RED, output); // Send the message to the victim
 new Float:x,Float:y,Float:z; 
 GetPlayerPos(victimid, x,y,z); // Get victim's position
 PlayerPlaySound(victimid, 1130, x, y, z); // Play the sound at that position
 SetPlayerVelocity(victimid, 0.0, 0.0, 0.2); // A 0.2 velocity in the Z direction will make the player to jump
}

public OnPlayerCommandText(playerid, cmdtext[])
{
 new cmd[128], tmp[28], vicid, vichp, idx;
 cmd = strtok(cmdtext, idx);
 if (strcmp("/slap", cmd, true) == 0)
 {
  tmp = strtok(cmdtext, idx);
  if(strlen(tmp) == 0) return SendClientMessage(playerid, WHITE, "USAGE: /slap [VictimID] [AmmountHP]");
  vicid = strval(tmp);
        tmp = strtok(cmdtext, idx);
        if(strlen(tmp) == 0) return SendClientMessage(playerid, WHITE, "USAGE: /slap [VictimID] [AmmountHP]");
        vichp = strval(tmp);
        Slap(vicid, vichp, playerid);
  return 1;
 }
 else if (strcmp("/slay", cmd, true) == 0)
 {
     tmp = strtok(cmdtext, idx);
  if(strlen(tmp) == 0) return SendClientMessage(playerid, WHITE, "USAGE: /slay [VictimID]");
  vicid = strval(tmp);
  SetPlayerHealth(vicid, 0.0);
  new name[64], output[128];
  GetPlayerName(playerid, name, 64);
  format(output, 128, "You have been slayed by %s!", name);
  SendClientMessage(vicid, RED, output);
  return 1;
 }
 return 0;
}

Saturday, January 8, 2011

XNA Tutorial: Simulate Gravity [Throw an Object] #2

Here is the code

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace FallingBall
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D ball; Vector2 ballpos = Vector2.Zero; // The position of the ball in 2D space (X,Y)
        Texture2D ball2; Vector2 ball2pos = Vector2.Zero;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            // Set the window height and width
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 920;
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            ball = Content.Load<Texture2D>("ball");
            ball2 = Content.Load<Texture2D>("ballsmall");
            ballpos.X = graphics.GraphicsDevice.Viewport.Width / 2 - ball.Width / 2; // Place the ball in the middle
            ballpos.Y = graphics.GraphicsDevice.Viewport.Height - ball.Height; // Place the ball on the bottom side of the window | the ground
            ball2pos.Y = graphics.GraphicsDevice.Viewport.Height;
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        //----------------------------------------------------------------------//
        double vi, t = 0; // vi - initial velocity | t - time
        double g = 520; // pixels per second squared | gravitational acceleration
        int keyState = 0;
        int kState = 0;
        double v, vx, vy, alpha, t2 = 0;
        //----------------------------------------------------------------------//
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();
            else if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                keyState = 1; vi = -820; // set a velocity of -820 pixels per second
            }
            else if(Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                kState = 1; v = -820;
                alpha = MathHelper.ToRadians(70f); // the angle at which the object is thrown (measured in radians)
                vx = v * Math.Cos(alpha);
                vy = v * Math.Sin(alpha);  
            }
            if (keyState == 1)
            {
                // the normal formula is: vi * t - g * t^2 / 2 and vi is positive, but here UP means decrease Y and DOWN means increase Y
                // that's why it looks strange
                ballpos.Y = (float)(vi * t + g * t * t / 2) + graphics.GraphicsDevice.Viewport.Height - ball.Height;
                t = t + gameTime.ElapsedGameTime.TotalSeconds; // calculate the time since the ball has left the ground
            }
            if (kState == 1)
            {
                ball2pos.Y = (float)(vy * t2 + g * t2 * t2 / 2) + graphics.GraphicsDevice.Viewport.Height - ball2.Height;
                ball2pos.X = (float)((vx * -1) * t2);
                t2 = t2 + gameTime.ElapsedGameTime.TotalSeconds;  
            }
            if (ballpos.Y > graphics.GraphicsDevice.Viewport.Height - ball.Height) // Don't allow the ball to go beyond the bottom side of the window
            {
                ballpos.Y = graphics.GraphicsDevice.Viewport.Height - ball.Height;
                keyState = 0;
                t = 0;
            }
            if (ball2pos.Y > graphics.GraphicsDevice.Viewport.Height - ball2.Height) 
            {
                ball2pos.Y = graphics.GraphicsDevice.Viewport.Height - ball2.Height;
                kState = 0;
                t2 = 0;
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            // Draw the ball
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
            spriteBatch.Draw(ball, ballpos, Color.White);
            spriteBatch.Draw(ball2, ball2pos, Color.White);  
            spriteBatch.End(); 

            base.Draw(gameTime);
        }
    }
}

Thursday, January 6, 2011

XNA Tutorial: Simulate Gravity [Jumping Ball] #1

Here is the code

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace FallingBall
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D ball; Vector2 ballpos = Vector2.Zero; // The position of the ball in 2D space (X,Y)
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            // Set the window height and width
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 920;
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            ball = Content.Load<Texture2D>("ball");
            ballpos.X = graphics.GraphicsDevice.Viewport.Width / 2 - ball.Width / 2; // Place the ball in the middle
            ballpos.Y = graphics.GraphicsDevice.Viewport.Height - ball.Height; // Place the ball on the bottom side of the window | the ground
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        //----------------------------------------------------------------------//
        double vi, t = 0; // vi - initial velocity | t - time
        double g = 520; // pixels per second squared | gravitational acceleration
        int keyState = 0;
        //----------------------------------------------------------------------//
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();
            else if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                keyState = 1; vi = -820; // set a velocity of -820 pixels per second
            }
            if (keyState == 1)
            {
                // the normal formula is: vi * t - g * t^2 / 2 and vi is positive, but here UP means decrease Y and DOWN means increase Y
                // that's why it looks strange
                ballpos.Y = (float)(vi * t + g * t * t / 2) + graphics.GraphicsDevice.Viewport.Height - ball.Height;
                t = t + gameTime.ElapsedGameTime.TotalSeconds; // calculate the time since the ball has left the ground
            }
            if (ballpos.Y > graphics.GraphicsDevice.Viewport.Height - ball.Height) // Don't allow the ball to go beyond the bottom side of the window
            {
                ballpos.Y = graphics.GraphicsDevice.Viewport.Height - ball.Height;
                keyState = 0;
                t = 0;
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            // Draw the ball
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
            spriteBatch.Draw(ball, ballpos, Color.White);
            spriteBatch.End(); 

            base.Draw(gameTime);
        }
    }
}

Or download the solution