Tacit
Tacit

Reputation: 908

2 in a row game in c#

the board

above is the image of the board

i am finding it hard to work out how to detect 2 color in a row to determine winner with out using brute-force enumeration..

i have an algorithm and i have been trying to implement it but i cant seem to get it working would anyone know how to do this.. would be great help thanks..

i want to detect winner diagonal vertical and horizontal..

p.s i don't normally ask for solutions but this time i really need some help. many thanks

here is the code that i have for the program that allows u to put the peaces

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        private Button[] btns;
        private Button[] btns2;
        private Button[] btns3;
        public Color[] col;
      //  public var x;

        public Form1()
        {
            InitializeComponent();

            btns = new Button[2] { button2, button3 };
            btns2 = new Button[2] { button4, button5 };
            btns3 = new Button[2] { button9, button8 };
            col = new Color[2] { Color.Red, Color.Yellow };
           Color x = col[0];
            Color y = col[1];


        }



        private void Form1_Load(object sender, EventArgs e)
        {

            foreach (var btn in btns)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }

            foreach (var btn in btns2)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }
            foreach (var btn in btns3)
            {
                btn.Enabled = false;
                btn.BackColor = Color.LightCyan;
            }
        }




        public int state;
        int cc = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            foreach (var btn in btns)
            {
                  {
                    if (!btn.Enabled)
                    {
                        btn.Enabled = true;

                        if (cc == 0)
                        {
                            cc = 1;
                            btn.BackColor = col[0];

                        }
                        else
                        {
                            cc = 0;
                            btn.BackColor = col[1];
                        }



                        return;
                    }

                }
            }       
        }


        private void button6_Click(object sender, EventArgs e)
        {
            foreach (var btn in btns2)
            {
                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = col[0];
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = col[1];

                    }



                    return;
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {

            foreach (var btn in btns3)
            {
                if (!btn.Enabled)
                {
                    btn.Enabled = true;

                    if (cc == 0)
                    {
                        cc = 1;
                        btn.BackColor = col[0];
                    }
                    else
                    {
                        cc = 0;
                        btn.BackColor = col[1];

                    }



                    return;
                }
            }

        }
    }
}

Upvotes: 2

Views: 565

Answers (5)

CodeCaster
CodeCaster

Reputation: 151604

You should not be doing this logic with buttons. Create a game class that implements the logic and that you can control by function calls containing X and Y parameters.

Then in each button click, you call the game logic like game.MakeMove(0, 0); if the button in the top left is clicked.

Profit of this: it is testable and the user interface can easily be changed.

Upvotes: 4

fegemo
fegemo

Reputation: 2594

You should consider using a multidimensional array to represent your data - buttons. In other words, a matrix.

Basically, you could declare your buttons like this:

private Button[,] buttons = new Button[2, 3];

An MSDN page explains how multidimensional arrays work.

Then, you could iterate on the array to detect any logic - horizontal, vertical, diagonal matching, etc. You could write something like this:

bool hasAWinner = false;
// for each line
for (int i = 0; i < 2; i++)
    Dictionary<Color, int> numberOfbuttonsWithColor = new Dictionary<Color, int>();
    numberOfbuttonsWithColor[Color.Red] = 0;
    numberOfbuttonsWithColor[Color.Yellow] = 0;

    // detect if there is at least two buttons of the same color
    for (int j = 0; j < 3; j++) {
        Color currentButtonColor = buttons[i,j].BackColor;
        numberOfbuttonsWithColor[currentButtonColor]++;
        if (numberOfbuttonsWithColor[currentButtonColor] == 2) {
            hasAWinner = true;
            break;
        }
    }

    if (hasAWinner) break;
}


// execute victory actions
if (hasAWinner) {
    Console.writeline(String.format("Color {0} wins!", currentButtonColor);
}

Upvotes: 1

SoManyGoblins
SoManyGoblins

Reputation: 5927

How about this.

Name each button after its column and row. i.e. btn00 (top left), btnNN (bottom right, with N being the amount of rows and columns, assuming a square), etc.

On each event handler, save the name of the clicked button, and its color. Then itereate over each color's collection of clicked button and compare indexes. If you find two button names that match the following criteria, it's two in a row:

if ((Math.Abs(index0ButtonA - index0ButtonB) == 1 && index1ButtonA == index1ButtonB) || ( Math.Abs(index1ButtonA - index1ButtonB) == 1 && index0ButtonA == index0ButtonB)
{
     twoInARow = true;
}

Upvotes: 0

Jesse Carter
Jesse Carter

Reputation: 21147

Here's what I think the logical approach would be without any code cause I'm at work at the moment and can't test anything out. You need to arrange your buttons or pieces or whatever your game will ultimately be in some kind of 2 dimensional array/collection with corresponding values for the X and Y axis.

When a button is clicked, you only need to check the relevant touching buttons to check for a potential match. For example. Lets imagine that the bottom left button is at position 0,0. If it is clicked you simply need to check the buttons at 1,0 and 0,1 to see if they are the same color to know a match has been made.

This can be easily extended for however many matches you need for a valid set. It also allows you to avoid the "brute force" approach. In the exact same scenario as before if you are looking for 4 in a row and 0,1 isn't the same color you don't need to check 0,2 or 0,3 or anything else along that axis because we already know there is no match there.

Upvotes: 1

Bobson
Bobson

Reputation: 13706

Two options. The simpler one is to create a Button[][] array, and populate it so that it matches the actual locations of the buttons. Then you can check other buttons by index.

The more complicated one is to create a subclass of Button which knows it's own position in the grid (X and Y properties) and knows how to find an adjoining button. Then you can get a list of all adjoining buttons of the same color, and build up a chain that way.

Upvotes: 1

Related Questions