Our members are dedicated to PASSION and PURPOSE without drama!

Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - VLS

#326
Mixed / 36-unit parachute
November 20, 2012, 03:52:15 AM
This one is a progression in RISK, meaning you keep the same 1 unit amount each bet but vary the location, reducing covered amount of numbers looking for more payout without having to rise.

[attachimg=#]

Vic
#327
Straight-up / Hot Numbers thread
November 18, 2012, 02:00:09 PM
This is a repository for definitions/views regarding hot numbers.

#328
Money Management / "Boom!" positive progression
November 17, 2012, 11:11:41 PM
The "boom" positive progression is intended to exploit the common happening of a location showing multiple times within a cycle.

This is entirely cycle-based, which means you should never deviate from the max. spin that closes it.

You assign the amount of units of a payout to face the cycle.

The basis is that you will re-invest the units won, divided by the number of spins left to cycle-end.

Example: You are betting a single number and get a hit at spin 15.

Cycle = 36
Hit at = 15

36 - 15 = 21

21 is the amount of spins left to sustain the bet.

How much to rise for those spins?

You rise by the result of payout divided by spins left.

In the case of a straight-up number, it is:

(36 * 1) / 21 = 1.71

So you add +1.71 units to your base bet for the rest of the cycle (tops).

1 + 1.71 = 2,71 units on the number now.

Shall you get another hit at -say- spin 23, your accounting will be:

36 - 23 = 13

13 spins to sustain the new bet.

(36 * 2.71) / 13 = 7,50 units on the number.

To be held for the next 13 spins tops.




Of course, there is a point in which you must take your wins, so it is advisable to take profits when on the plus, especially when playing several numbers this way at the same time.

At all times you know you are risking EXACTLY one payout of your base unit.

In the case of a single number it is 36 units, but in the event of having concatenated wins in the cycle, the ROI can rise handsomely.

This can be extrapolated to nice-paying locations such as splits or streets. Lower-paying locations do not offer enough for it to really go “boom!”, so you better stick to the higher-paying betting locations when considering this.

Regards.
Vic
#329
Hello dear friends,

Just wanted to mention the fine fellows in the forum's software section aren't in direct competition with what I envision and aim for our software offering here.

I aim to create a roulette framework to enable the everyday user to create their own trackers, testers, clickers and bots. A true "do it yourself" set, where the user has pre-set modules at their disposal (the $5.99 part) and they can code the very minimum to achieve by extending it.

This means that I am working hard to *CREATE* able people like nOrMy or Ophis with the least learning curve. If I succeed you'll be able to simply hire the framework for $5.99 and code against it to serve your own needs; without me, Normy nor any other person in between  :thumbsup:  That's what I aim to attain. To create a product that let users deliver value to themselves; the realization of my motto: "Making a living by helping others achieve".

As far as I know there isn't anything quite like it on the market, not even RX, since while it's true that RX has a scripting language, you are "jailed" with it because you are limited to what RX offers and can't really extend the core feature-set by yourself.

Under the way I'm structuring the framework, you are OPEN to re-using modules from other people, whatever their favorite programming language might be. It's a common API.

So, please let's receive the fellows bringing in their programming skills to our place with arms wide open: we aren't competing. Fellow coders are offering their fine programs; we are ultimately aiming to offer a framework which people can code on their own to become self-sufficient.

Regards.
Vic
#330
Off-topic / Miscellaneous
November 15, 2012, 02:48:04 PM
Quote from: TwoCatSam on November 15, 2012, 02:19:14 PM
Two old men were talking about going to the bathroom.  The first had a terrible time.  Slow stream and constipation.  The second allowed as how he could pee like did when he was twenty and his bowels and bladder both worked a 7:30 each morning.

"Wow!  That must be wonderful!"
"Not really.  I sleep 'till nine!"


:)) ^-^


Good one.
#331
General Discussion / Casino Watchdog sites
November 12, 2012, 08:35:33 PM
May I add the most popular (for a reason):

http://casinomeister.com

:thumbsup:
#333
Meta-selection / T-peaters
November 11, 2012, 10:24:43 PM
"T-peaters" stand for Time-repeaters.

The concept is this: You track locations by keeping note on how many spins back the current number showed before and target the most repeating gaps by dynamically betting the numbers, counting from the current spin backwards.


This gives you a sort of fixed-length table on which the numbers to bet are changing spin to spin as they pass through the slots.


e.g. say you must bet 5 backwards, 9 backwards, 17 backwards... you keep looking back the same spin to spin, but the actual numbers to bet change as new numbers show and "push" the older numbers down.
#334
Positive / Intra-session percentage rise
November 08, 2012, 03:30:51 PM
This is a topic which deserves more focus and discussion, since it can make A LOT of difference in your session's results, and hence in your gambling life as it is compounded by all individual sessions' outcomes.


In any case, intra-session % rise enables you to either reach your win goal faster with the same initial amount of risked units OR explode your profits to a substantially greater amount when you let it run wildly, even accounting for the loss that ends the .


There are two "sweet spots" as to the percentage rate increase:


50% rise:


I call it "Inflation".


This is to be used with betting methods without a defined win goal.


You reinvest 50% of every won bet and use it to further increase your base unit in the current session.


The other 50% is locked as your increasing session profit.


The session ends when the total amount of starting session units are depleted, having your locked units as net profit.


100% rise:


I call it "Explosion"


This is to be used with what would regularly be a progressive method with a specific percentage target or preferably with a flat betting method, so the win goal is achieved faster and you go out of the table quicker, with less time exposure.


You reinvest 100% of your won bets into your current base unit, entirely compounding it. This is why there must be a defined win goal; you only get the loot after your session goal is reached, with the big advantage of getting it faster with the same amount of initial units risked.


In some high-paying bet locations such as straight numbers and splits the difference made by explosion can be highly noticeable; furthermore, by means of the lesser amount of time spent in the session, it can turn what could have been a losing session into a winning one.


A total must for methods using a fixed-percentage of wins.
#335
Mixed / Mixed INTER-SESSION Money Management
November 08, 2012, 02:26:47 PM
This is a most-interesting topic to elaborate on.

There are plenty of mixed inter-session MM rules; yet one set I particularly like being:

Winning session procedure:

33% - Added to attack session's bank (increase base unit for next session)
33% - Add units to the last session bankroll of the lifetime reserve.
34% - Player profit.

Losing session procedure:

Attack bankroll returns to base unit.




Money management goal:

Compounding profits on concatenated winning sessions.

Safeguarding the lifetime bankroll on concatenated losing sessions.
#336
Off-topic / DIY (Do it yourself)
November 08, 2012, 03:12:56 AM
I like the DIY culture. A lot.

When I was younger I would tear the home's radio apart and my remote-controlled cars would later serve for remote-controlled motors for the most various purposes. It sure starts the "bug" to know and create...

As an adult in the IT field, I like assembling my own computer(s), creating programs and in general I like the feeling of achievement derived from the "DIY way", rather than from the canned way.

Of course, I'm not an extremist and wouldn't do my own soap or anything like that. But hey! Some people do.

This thread is devoted to DIY projects which might be interesting to the general public, including extreme ones.

Feel free to add DIY projects you happen to like!
#337
Meta-selection / Production and Recovery
November 05, 2012, 02:21:25 AM

Production and Recovery is a two-layered strategy which many people use, even without realizing.

In the most purist mindset:

       
  • The production layer is the one making the units.
  • The recovery layer is the one that kicks-in when the production layer misses and its aim is to "patch" the balance to break even point.



This P&R combo can take many different forms, including combining VERY DIFFERENT approaches, that complement each other in the overall strategy.

Take for instance the combination:

Production: Last 5 lines.
Recovery: 36-unit parachute.

Last 5 lines is a flat bet covering 30 numbers with 5 chips. You can expect long sets of concatenated wins when the further-behind becomes a sleeper. It has a tendency to do that already.

The 36-unit parachute is a progression in risk. It has varied payout; at some levels netting more than +5.



If you may, a standard progression is also a P&R combo:

- First step of progression = Production. A hit on it nets/makes the units.

- All other steps = Recovery. The goal being to bring the balance back to even after missing production/first step.





There are many other combinations or schemes for Production and Recovey combos.

In this thread we can see several of them; perhaps one of them suits you.
#338
Which online casino(s) have earned your personal choice?


Based on first-hand experience.

We want to know about the Good ones in your personal list  :thumbsup:  those which have delivered to you on time, and offer you the best playing conditions so you've recurred with them...


(the bad and the ugly can have their own dedicated threads!)
#339
General Discussion / The trackers I owe
November 02, 2012, 05:34:49 AM
Fellows,

After the removal of the other forums there were some fine folks left with their trackers hanging.

Please feel free to contact me in order to ask for a release in here. Even if free, I owe them to you and I apologize. If you still need them I am still here to make it right.

Thanks.
#340
They say all bet selections are equal... long term.

While it is true all bet selections are scheduled to even out "in the long run". Let's shift the focus to the short run, using bet selections as part of a STRATEGY, not sticking to them like a robot while they are losing the lot, only when they are presenting a good (measurable) strike rate.
#341
Multiple locations / Delayed parachute
October 28, 2012, 10:16:33 PM
This one is based on the "parachuting" methodology.

For those who might not be familiar with it, the parachute is a progression in risk, simply going to the next location of the following ladder:


       
  • Even chance.
  • Dozen/Column
  • Double-street.
  • Quad/Corner
  • Street
  • Split.

This is delayed because it's based on CYCLES, unlike the traditional 36-unit parachute which is based on SPINS.
#342
Community Software / Suggest a small program
October 28, 2012, 08:10:10 PM
If you can ram the description of a tracker in a small paragraph, I can give it a go.
One-liners would be better  ;)

I'm talking the type:

- Tracker for last 5 double-streets to repeat.
- Tracker for hottest split in the last 36 spins.
- Tracker for the most regular dozen/column in the last 10 cycles.

You get the gist!




At times I like a small release. Perhaps to try a new approach, language or technique when building it...


Your proggie gets delivered as a free release for the community to enjoy.

Vic
#343
Community Software / Your operative system
October 28, 2012, 07:49:35 PM
This is a most-relevant question for our software.

True; with the advancement of virtualization, the limits of "platform the software runs on" are getting "blurry"; but still, this is important to determine the native platform to program our software for.

If you use multiple platforms, you can tick the one you use the most.
#344
Straight-up / Eight Time Dimension Dwellers
October 25, 2012, 03:43:07 PM
This selection is very easy to use, even without a tracking sheet.

The following are the transformed #'s (figures):

1: 1, 10, 19, 28
2: 2, 11, 20, 29
3: 3, 12, 21, 30
4: 4, 13, 22, 31
5: 5, 14, 23, 32
6: 6, 15, 24, 33
7: 7, 16, 25, 34
8: 8, 17, 26, 35
9: 9, 18, 27, 36

The selection is based on the last 9 spins.

You keep track of the last figure to repeat within that 9-spin window and bet it for -at most- 9 further spins at most. A hit closes the attack. You should never go past 9 spins; it's the break even point.

You only bet the last two figures that have repeated (eight numbers max., hence the name). Replacing the oldest figure with the newest one enabled.

Each new figure starts its own "bets counter" afresh, with its own 9 spins of attack.




Don't dismiss it because of its simplicity. This can be a streaky bet.

Since this is a time dimension selection, you use strictly the last 9 spins. One full cycle for the 4-number figure.

You are attempting to catch the "bursts" of hits and are "going with the numerical stream".




This is another one to be added to the framework.
#345
Straight-up / The "Dozen twins"
October 22, 2012, 01:59:15 AM
 The dozen twins bet selection is based on these premises:

       
  • Out of the three dozens, two will usually be more "loaded", with one lagging behind.
  • Out of the the three columns, two will usually be more "loaded", with one lagging behind.
  • The two loaded dozens, and the two loaded columns are likely to make "matches" on them if we make both "overlap". i.e. if we were placing them one over the other. Seeing two neighbor/touching numbers on the same exact overlapping location, there will be 4 numbers that will happen to match or pair on both loaded areas. These two neighbors are the "Twins"; the overlapping dozen twins.
#346
Here's a free release for all the community  :)

Random Unique Line Generator is an aid for those players who need to generate a text string with all locations in a non-repetitive fashion.

Perhaps to create unique "virtual wheels", to bet for or against those unique patterns or to use them as part of a bigger strategy.

Here it is. Enjoy!

Download:
[attachmini=1]




Assembly works on Windows:

[attachimg=2]

As well as Linux/Mac (Via MONO runtime):

[attachimg=3]




It was programmed in cross-platform C#, targeting .NET 2.0 for maximum compatibility.

Main form's source code:

Code (csharp) Select

// C-sharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;


/*
* Source code provided as a compliment. Use for your own learning.
* Feel free to submit your modifications for inclusion at: http://betselection.cc
* Do *not* publicly distribute modified versions (as to keep one (1) canonical version).
* Thanks for appreciating this program. Enjoy!
* Vic
*/


// Main program's namespace
namespace BetSelection_cc_Random_Unique_Line_Generator_v0_1
{
    // Program's form
    public partial class Form1 : Form
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// Start-up routine
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            // Check numbers's radio
            rbN.Checked = true;


            // Set tooltips
            setTooltip(bFile, "Save to file", "Click to pick target file");
            setTooltip(bClipboard, "Copy to clipboard", "Copies generated lines to clipboard");
            setTooltip(tbSep, "Escape sequences:", "\\n = new line. \\t = tabulator.");
        }


        /// <summary>
        /// Handle generate button
        /// </summary>
        private void bGenerate_Click(object sender, EventArgs e)
        {
            // Declare a string array for lines
            string[] lines = new string[0];


            // Declare single string for all lines
            string all_lines = "";
           
            // Act on selected radio button
            switch(getCheckedRadioButton().Name)
            {
                // Numbers
                case "rbN":
                    // Set lines
                    lines = generateRandomLines(37);
                    break;


                // Splits
                case "rbS":
                    lines = generateRandomLines(18);
                    break;


                // Streets
                case "rbSt":
                    lines = generateRandomLines(12);
                    break;


                // Double-streets
                case "rbDS":
                    lines = generateRandomLines(6);
                    break;


                // Dozens/columns
                case "rbDC":
                    lines = generateRandomLines(3);
                    break;
            }


            // Set all_lines
            foreach(string line in lines)
            {
                // Append current line
                all_lines += line + Environment.NewLine;
            }


            /* Handle Clipboard or File*/


            // Message
            string msg = "";


            switch (((Button)sender).Name)
            {
                // Set lines into clipboard
                case "bClipboard":
                   
                    // Clear it
                    Clipboard.Clear();


                    // Set data to it
                    Clipboard.SetText(all_lines);


                    // Set message
                    msg = "Generated lines have been copied to clipboard.";
                   
                    break;


                // Write lines to file
                case "bFile":
                   
                    // Prepare save file dialog
                    sfdLines.Filter = "Text files|*.txt|All files|*.*";
                    sfdLines.Title = "Save generated lines to file";


                    // Show save file dialog
                    sfdLines.ShowDialog();


                    // Check if there's something
                    if (sfdLines.FileName != "")
                    {
                        // Insert lines into file
                        File.WriteAllText(sfdLines.FileName, all_lines);


                        // Set message
                        msg = "Saved all generated lines to:" + Environment.NewLine + sfdLines.FileName;
                    }
                    else
                    {
                        // Cut the flow
                        return;
                    }
                   
                    break;
            }


            // Show success message
            MessageBox.Show(msg, "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }


        /// <summary>
        /// Ancillary function to assist in generation
        /// </summary>
        /// <param name="elements">Items to hold</param>
        /// <returns>String array with a random sequence of elements on each string</returns>
        string[] generateRandomLines(byte elements)
        {
            // String array to hold all lines
            string[] lines = new string[Convert.ToInt32(nudTimes.Value)];


            // Byte array to hold a generated line
            byte[] line = new byte[elements];


            // Set amount to add. 0 for singles and splits, 1 for the rest
            byte add = Convert.ToByte(elements == 37 || elements == 18 ? 0 : 1);


            // Set variable for splits translation
            string[] splits = new string[] {"1/4", "2/5", "3/6", "7/10", "8/11", "9/12", "13/16", "14/17", "15/18", "19/22", "20/23", "21/24", "25/28", "26/29", "27/30", "31/34", "32/35", "33/36"};


            // Populate with sequential values
            for (byte seq = 0; seq < line.Length; ++seq)
            {
                // Set current
                line[seq] = Convert.ToByte(seq + add);
            }


            // Generation loop
            for (int g = 0; g < Convert.ToInt32(nudTimes.Value); ++g)
            {
                // Declare separator
                string sep = tbSep.Text;


                // Check if separator must be set to newline or tab
                switch (tbSep.Text)
                {
                    // New line
                    case "\\n":
                        sep = Environment.NewLine;
                        break;


                    // Tab
                    case "\\t":
                        sep = "\t";
                        break;
                }


                // Prepare a "good-enough" seed
                int seed = Convert.ToInt32(Regex.Replace(Guid.NewGuid().ToString().ToLower(), "[a-z-]", "").Substring(0, 9));
               
                // Shuffle
                new Random(seed + g).Shuffle(line);


                // Declare variable for resulting line
                string r_line = "";


                // Loop through elements in order to build the line string
                for (byte l = 0; l < line.Length; ++l)
                {
                    // Add current, accounting for split, separator and excluding last instance of it
                    r_line += (elements == 18 ? splits[line[l]] : line[l].ToString()) + (l != line.Length - 1 ? sep : "");
                }


                // Add it
                lines[g] = r_line;
            }


            // Return result
            return lines;
        }


        /// <summary>
        /// Retrieve currently checked location
        /// </summary>
        /// <returns>The checked RadioButton</returns>
        private RadioButton getCheckedRadioButton()
        {
            // Iterate through form controls
            foreach (Control c in this.Controls)
            {
                // Check if it's a RadioButton
                if (c is RadioButton)
                {
                    // Cast
                    RadioButton r = c as RadioButton;
                   
                    // Test for check
                    if(r.Checked)
                    {
                        // It's checked, return it
                        return r;
                    }
                }
            }


            // Nothing
            return null;
        }


        /// <summary>
        /// Launches BetSelection site when program ends.
        /// </summary>
        private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
        {
            // Launch BetSelection.cc in default browser
            System.Diagnostics.Process.Start("http://betselection.cc");
        }


        /// <summary>
        /// Creates and attaches a tooltip to control
        /// </summary>
        /// <param name="ctrl">Control to which the tooltip wil be attached to</param>
        /// <param name="title">Tooltip's title</param>
        /// <param name="text">Tooltip's text</param>
        private void setTooltip(Control ctrl, string title, string text)
        {
            ToolTip ttToolTip = new ToolTip();
            ttToolTip.ToolTipTitle = title;
            ttToolTip.UseFading = true;
            ttToolTip.UseAnimation = true;
            ttToolTip.ShowAlways = true;
            ttToolTip.AutoPopDelay = 5000;
           
            // Shorter initial delay for separator
            ttToolTip.InitialDelay = (ctrl.Name == "tbSep" ? 100 : 1000);
           
            ttToolTip.ReshowDelay = 500;
            ttToolTip.SetToolTip(ctrl, text);
        }


        /// <summary>
        /// Status label link
        /// </summary>
        private void tsslLink_Click(object sender, EventArgs e)
        {
            // Launch BetSelection.cc site
            System.Diagnostics.Process.Start("http://betselection.cc");
        }


        /// <summary>
        /// Handles MouseEnter event for RadioButtons
        /// </summary>
        private void rb_MouseEnter(object sender, EventArgs e)
        {
            // Change to red
            ((RadioButton)sender).ForeColor = Color.Red;
        }


        /// <summary>
        /// Handles MouseLeave event for RadioButtons
        /// </summary>
        private void rb_MouseLeave(object sender, EventArgs e)
        {
            // Change back to black
            ((RadioButton)sender).ForeColor = Color.Black;
        }
    }


    // Generics to enable Shuffle
    static class RandomExtensions
    {
        // Shuffle method
        public static void Shuffle<T>(this Random RNG, T[] array)
        {
            // Knuth-Fisher-Yates shuffling
            for (int i = array.Length - 1; i > 0; i--)
            {
                int n = RNG.Next(i + 1);
                Swap(ref array[i], ref array[n]);
            }
        }


        // Swap method
        static void Swap<T>(ref T lhs, ref T rhs)
        {
            T temp;
            temp = lhs;
            lhs = rhs;
            rhs = temp;
        }
    }
}


// Required for RandomExtensions
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
         | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }
}


Full project sources:
[attachmini=4]
#347
Positive / *REVERSED* delayed ATILA
October 20, 2012, 09:55:31 AM
The reversed ATILA's procedure is simple to grasp.

While the ATILA rises on a loss, the REVERSED ATILA rises on a win.

So shall you start with the line:

1 1 1 1 1 1 1 1 1

You stay using this line until you get a hit.

Only then do you proceed to rise one element:

2 1 1 1 1 1 1 1 1

And stay with this new line until you get another hit:

2 2 1 1 1 1 1 1 1

Staying with it until your next hit:

2 2 2 1 1 1 1 1 1

And so on.




This reversed ATILA version only lowers units if your next bet covers the deficit IN FULL.

Let me explain.

Say you are:

4 4 4 3 3 3 3 3 3

And you get a hit, which takes you to -21 below of your previous high.

Staying at:

4 4 4 3 3 3 3 3 3

Would be an overkill.

You then lower to:

1 1 1 1 1 1 1 1 1

Since a hit on next spin would cover the -21 and get you to a new high.

36 - 9 = 27

You -21 is covered in full with a hit on next bet.

Apply the same principle to go back to:

2 2 2 2 2 2 2 2 2

72 - 18 = 54

And so on.




...The "delayed" part of this version of the ATILA comes naturally since you aren't rising on every spin, but you are making your rising time happen only after a win, skipping the spins in between and hence the delay.
#348
Money Management / *DELAYED* ATILA
October 20, 2012, 09:24:12 AM
This means applying the ATILA progression, raising an element with a condition other than a simple loss.

It could be two losses. It could be 3 or more losses.

It could be rising after a lost cycle.

As long as you don't raise after every single lost spin, it's a delayed ATILA.



For instance, if you were to use the ATILA on two columns/dozens, you would raise your betting line:

1 1

If you miss a hit in a full cycle (3 spins for dozens):

2 1

Then shall you miss another cycle:

2 2

And so on. As long as you don't raise every spin, you are using the delayed version of the ATILA progression.
#349
Negative / ATILA progression
October 20, 2012, 09:17:50 AM

Originally intended for nine (9) numbers.


You start with a line of 1's, each representing the bet on a number:

1 1 1 1 1 1 1 1 1


When you lose a spin, you rise one element of your line:


2 1 1 1 1 1 1 1 1


When you lose another spin, you rise another element:


2 2 1 1 1 1 1 1 1


And so on:


2 2 2 1 1 1 1 1 1


In the same fashion, one element per spin without a hit:


2 2 2 2 1 1 1 1 1


2 2 2 2 2 1 1 1 1


2 2 2 2 2 2 1 1 1


2 2 2 2 2 2 2 1 1


2 2 2 2 2 2 2 2 1


2 2 2 2 2 2 2 2 2

When you run finish rising your line's 9th element, you start rising from the beginning again:


3 2 2 2 2 2 2 2 2


3 3 2 2 2 2 2 2 2

3 3 3 2 2 2 2 2 2


3 3 3 3 2 2 2 2 2


3 3 3 3 3 2 2 2 2


And so on...







ATILA recommends lowering one element (the most recently risen) on a win.


This means if you are at -for example-:


2 2 2 2 2 2 2 1 1


You go back to:


2 2 2 2 2 2 1 1 1


And if another hit:


2 2 2 2 2 1 1 1 1


And so on:


2 2 2 2 1 1 1 1 1


Rising one element on a loss:


2 2 2 2 2 1 1 1 1


And lowering one element on a win:


2 2 2 2 1 1 1 1 1
#350
Generate a random line of double-streets with ease:

[attachimg=1]

Download: [attachmini=2]




Program's source code:

#include <windows.h>
#include <algorithm>
#include <vector>
#include <sstream>
#include <iterator>
#include <ctime>


// Resolve namespace
using namespace std;


// Set class name
const char g_szClassName[] = "vWindowCLS";


// Text to print
ostringstream g_oss;


// Unique number struct
struct c_unique {
  int current;
  c_unique() {current=0;}
  int operator()() {return ++current;}
} UniqueNumber;


// Rectangle structure
RECT g_rect;


/*
* Generates a random double-street line,
* prints it to main form and places it on the keyboard
*/
void gen_line(HWND hwnd)
{
   // Create a vector holding numbers 1 to 6
   vector<int> vec (6);
   
   // Fill it with numbers 1 to 6
   generate( vec.begin(), vec.end(), UniqueNumber );   
   
   // Seed rand
   srand(rand() % time(0));
   
   // Shuffle the vector
   random_shuffle( vec.begin(), vec.end() );
   
   // Reset g_oss
   g_oss.str("");
   
   // Convert all but the last element to avoid a trailing ","
   copy(vec.begin(), vec.end()-1, ostream_iterator<int>(g_oss, ","));


   // Now add the last element with no delimiter
   g_oss << vec.back();
   
   /* Set clipboard to generated line */
   if(OpenClipboard(hwnd))
   {
      // Declare memory block
      HGLOBAL glob;
     
      // Allocate memory
      glob = GlobalAlloc(GMEM_FIXED,32);
     
      // Copy text
      memcpy(glob,g_oss.str().c_str(),11);
     
      // Flush clipboard
      EmptyClipboard();
     
      // Set new data
      SetClipboardData(CF_TEXT,glob);
     
      // Close clipboard
      CloseClipboard();
     
      // Unlock memory
      GlobalUnlock(glob);
   }
   
   /* Invalidate rectangle */
   
   // Get rect
   GetClientRect(hwnd, &g_rect);
   
   // Invalidate rectangle
   InvalidateRect(hwnd, &g_rect, true);
}




LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE: // Program load
        case WM_LBUTTONUP: // Left-click
        case WM_RBUTTONUP: // Right-click
       
         // Call gen_line
         gen_line(hwnd);
         
      break;
     
      // Close window
        case WM_CLOSE:
       
            DestroyWindow(hwnd);
           
        break;
       
        case WM_PAINT:
         
         /* Paint the text*/
         HDC hDC;
         PAINTSTRUCT ps;
         hDC = BeginPaint(hwnd, &ps);
         
         GetClientRect(hwnd, &g_rect);   
         
         // Top, regular font
         DrawText(hDC, "Last random line:", -1, &g_rect,
         DT_SINGLELINE | DT_CENTER | DT_TOP);
         
         // Bottom, regular font
         DrawText(hDC, "Victor/VLS @ www.HobbyCode.tk", -1, &g_rect,
         DT_SINGLELINE | DT_CENTER | DT_BOTTOM);
         
         // Center, big font         
         HFONT hf;
         long lfHeight;


         lfHeight = -MulDiv(28, GetDeviceCaps(hDC, LOGPIXELSY), 72);


         hf = CreateFont(lfHeight, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman");


         SelectObject(hDC, hf);
   
         DrawText(hDC, g_oss.str().c_str(), -1, &g_rect,
         DT_SINGLELINE | DT_CENTER | DT_VCENTER);
         
         // Finish paint
         EndPaint(hwnd, &ps);
         
      break;
       
        // Destroy window
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
       
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;


    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);


    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }


    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "Click to generate",
        WS_OVERLAPPEDWINDOW  &~ WS_MAXIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);


    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }


    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);


    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}