Problem with C# Logic

Hi,

I made this Tic Tac Toe Game simulation. It will count the numbers of X and O per row.

At the end of the program there is some logic where "This is a tie" shows up 100% of the time. Do you have any ideas on what I did wrong?

Thanks!

   int x = 0;
        int o = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private void xWins()
        {
            x++;
        }

        private void oWins()
        {
            o++;
        }

        private void newGameButton_Click(object sender, EventArgs e)
        {

            winnerLabel.Text = "";
            // declare array size
            const int ROW = 3;
            const int COL = 3;
            int[,] values = new int[ROW, COL];

            int x = 0;
            int o = 0;
            // random number generators
            Random rand = new Random();


            // loop to create values in array
            for(int row = 0; row < ROW; row++)
            {
                for(int col = 0; col < COL; col++)
                {
                    values[row, col] = rand.Next(2);

                     //change 0,1 to X,O
                    char[] charvalues = new char[2];
                    charvalues [0] = 'O';
                    charvalues [1] = 'X';

                    // fill labels
                   topLeft.Text = charvalues[values[0,0]].ToString();
                   topCenter.Text = charvalues[values[0,1]].ToString();
                   topRight.Text = charvalues[values[0,2]].ToString();

                   middleLeft.Text = charvalues[values[1,0]].ToString();
                   middleCenter.Text = charvalues[values[1,1]].ToString();
                   middleRight.Text = charvalues[values[1,2]].ToString();

                   bottomLeft.Text = charvalues[values[2,0]].ToString();
                   bottomCenter.Text = charvalues[values[2,1]].ToString();
                   bottomRight.Text = charvalues[values[2,2]].ToString();

                   //Check HORIZONTAL lines for winner  
                   if (topLeft.Text == "X" & topCenter.Text == "X" & topRight.Text == "X") xWins();
                   if (middleLeft.Text == "X" & middleCenter.Text == "X" & middleRight.Text == "X") xWins();
                   if (bottomLeft.Text == "X" & bottomCenter.Text == "X" & bottomRight.Text == "X") xWins();
                   if (topLeft.Text == "O" & topCenter.Text == "O" & topRight.Text == "O") oWins();
                   if (middleLeft.Text == "O" & middleCenter.Text == "O" & middleRight.Text == "O") oWins();
                   if (bottomLeft.Text == "O" & bottomCenter.Text == "O" & bottomRight.Text == "O") oWins();

                   // Check VERTICAL lines for winner  
                   if (topLeft.Text == "X" & middleLeft.Text == "X" & bottomLeft.Text == "X") oWins();
                   if (topCenter.Text == "X" & middleCenter.Text == "X" & bottomCenter.Text == "X") xWins();
                   if (topRight.Text == "X" & middleRight.Text == "X" & bottomRight.Text == "X") xWins();
                   if (topLeft.Text == "O" & middleLeft.Text == "O" & bottomLeft.Text == "O") xWins();
                   if (topCenter.Text == "O" & middleCenter.Text == "O" & bottomCenter.Text == "O") oWins();
                   if (topRight.Text == "O" & middleRight.Text == "O" & bottomRight.Text == "O") oWins();

                   //Check DIAGONAL lines for winner  
                   if (topLeft.Text == "X" & middleCenter.Text == "X" & bottomRight.Text == "X") xWins();
                   if (topRight.Text == "X" & middleCenter.Text == "X" & bottomLeft.Text == "X") xWins();
                   if (topLeft.Text == "O" & middleCenter.Text == "O" & bottomRight.Text == "O") oWins();
                   if (topRight.Text == "O" & middleCenter.Text == "O" & bottomLeft.Text == "O") oWins();

                    // display winner

                    if (x == o | o == x)
                    {
                        winnerLabel.Text = "This is a tie";
                    }
                    else if (x > o)
                    {
                        winnerLabel.Text = "X Wins";
                    }
                    else if (o > x)
                    {
                        winnerLabel.Text = "O Wins";
                    }
                    else
                    {
                        winnerLabel.Text = "";
                    }


                }

            }
        }

Open in new window

LVL 3
Computer GuyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

n2fcCommented:
You need to review "scope of variables"...

In order for your xwins() and owins() routines to reference the SAME variable as other routines, the variables x and o must be global to all routines...

As automatic variables (default) each routine gets its own copy!

See:
http://stackoverflow.com/questions/5986051/c-sharp-static-variables-scope-and-persistence
Computer GuyAuthor Commented:
Do you have an example off of my code?
Computer GuyAuthor Commented:
I did remove the methods and just do it this way:

if (topLeft.Text == "X" & middleLeft.Text == "X" & bottomLeft.Text == "X") o++();

Open in new window


Where I declared int o = 0; at the top of the click method and I get O always winning now.
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Carl TawnSystems and Integration DeveloperCommented:
I can see a couple of immediate issues:

1) This line:
 if (x == o | o == x)

Open in new window

doesn't make any sense. You're doing two identical comparisons and doing a binary OR on the result.

2) Your logic appears to be wrong. You appear to be using the count of how many games each player has won to determine who won the current games. Those two things are logically separate.
Computer GuyAuthor Commented:
This is just a simulation of a game which would allow for x to win 3 times. I know, weird

When ever a winning set of x or o is present, I would count. At the end I would determine the winner.

What I was trying to do is if x and o both won twice it would be a tie.
Carl TawnSystems and Integration DeveloperCommented:
Actually, on closer inspection, you are using binary comparison everywhere when you should be using logical comparison.

Try this version (which still isn't 100% because you are randomly choosing X or O which can result in more of either character that there should be but it should at least correct the scoring logic):
        private void xWins()
        {
            x++;
        }

        private void oWins()
        {
            o++;
        }

        private void newGameButton_Click(object sender, EventArgs e)
        {
            winnerLabel.Text = "";
            // declare array size
            const int ROW = 3;
            const int COL = 3;
            int[,] values = new int[ROW, COL];

            // random number generators
            Random rand = new Random();

            x = 0;
            o = 0;

            // loop to create values in array
            for (int row = 0; row < ROW; row++)
            {
                for (int col = 0; col < COL; col++)
                {
                    values[row, col] = rand.Next(2);

                    //change 0,1 to X,O
                    char[] charvalues = new char[2];
                    charvalues[0] = 'O';
                    charvalues[1] = 'X';

                    // fill labels
                    topLeft.Text = charvalues[values[0, 0]].ToString();
                    topCenter.Text = charvalues[values[0, 1]].ToString();
                    topRight.Text = charvalues[values[0, 2]].ToString();

                    middleLeft.Text = charvalues[values[1, 0]].ToString();
                    middleCenter.Text = charvalues[values[1, 1]].ToString();
                    middleRight.Text = charvalues[values[1, 2]].ToString();

                    bottomLeft.Text = charvalues[values[2, 0]].ToString();
                    bottomCenter.Text = charvalues[values[2, 1]].ToString();
                    bottomRight.Text = charvalues[values[2, 2]].ToString();
                }
            }
             
            //Check HORIZONTAL lines for winner  
            if (topLeft.Text == "X" && topCenter.Text == "X" && topRight.Text == "X") xWins();
            if (middleLeft.Text == "X" && middleCenter.Text == "X" && middleRight.Text == "X") xWins();
            if (bottomLeft.Text == "X" && bottomCenter.Text == "X" && bottomRight.Text == "X") xWins();
            if (topLeft.Text == "O" && topCenter.Text == "O" && topRight.Text == "O") oWins();
            if (middleLeft.Text == "O" && middleCenter.Text == "O" && middleRight.Text == "O") oWins();
            if (bottomLeft.Text == "O" && bottomCenter.Text == "O" && bottomRight.Text == "O") oWins();

            // Check VERTICAL lines for winner  
            if (topLeft.Text == "X" && middleLeft.Text == "X" && bottomLeft.Text == "X") oWins();
            if (topCenter.Text == "X" && middleCenter.Text == "X" && bottomCenter.Text == "X") xWins();
            if (topRight.Text == "X" && middleRight.Text == "X" && bottomRight.Text == "X") xWins();
            if (topLeft.Text == "O" && middleLeft.Text == "O" && bottomLeft.Text == "O") xWins();
            if (topCenter.Text == "O" && middleCenter.Text == "O" && bottomCenter.Text == "O") oWins();
            if (topRight.Text == "O" && middleRight.Text == "O" && bottomRight.Text == "O") oWins();

            //Check DIAGONAL lines for winner  
            if (topLeft.Text == "X" && middleCenter.Text == "X" && bottomRight.Text == "X") xWins();
            if (topRight.Text == "X" && middleCenter.Text == "X" && bottomLeft.Text == "X") xWins();
            if (topLeft.Text == "O" && middleCenter.Text == "O" && bottomRight.Text == "O") oWins();
            if (topRight.Text == "O" && middleCenter.Text == "O" && bottomLeft.Text == "O") oWins();

            // display winner

            if (x == o)
            {
                winnerLabel.Text = "This is a tie";
            }
            else if (x > o)
            {
                winnerLabel.Text = "X Wins";
            }
            else if (o > x)
            {
                winnerLabel.Text = "O Wins";
            }
            else
            {
                winnerLabel.Text = "";
            }
        }

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
@Carl - | and & have dual meanings in C#.  When used on integral types, they compute the bitwise OR and AND of the operands.  When used on boolean types, they compute the logical OR and AND of the operands.

https://msdn.microsoft.com/en-us/library/kxszd0kx.aspx
https://msdn.microsoft.com/en-us/library/sbf85k1c.aspx

Consider the following:
using System;

namespace EE_Q28651011
{
	class Program
	{
		static int x = 0xf8;
		static int y = 0x3f;
		static int zAND = 0x38;
		static int zOR = 0xff;

		static void Main(string[] args)
		{
			Console.WriteLine("{0} is equal to {1} OR {0} is equal to {2}: {3}", x, zOR, zAND, x == zOR | x == zAND);
			Console.WriteLine("{0} is equal to {1} OR {0} is equal to {2}: {3}", y, zOR, zAND, y == zOR | y == zAND);
			Console.WriteLine("{0} AND {1} is equal to {2}: {3}", x, y, zAND, (x & y) == zAND);
			Console.WriteLine("{0} OR {1} is equal to {2}: {3}", x, y, zOR, (x | y) == zOR);

			zAND = x;
			zOR = y;
			Console.WriteLine("{0} is equal to {1} OR {0} is equal to {2}: {3}", x, zOR, zAND, x == zOR | x == zAND);
			Console.WriteLine("{0} is equal to {1} OR {0} is equal to {2}: {3}", y, zOR, zAND, y == zOR | y == zAND);
			Console.WriteLine("{0} is equal to {1} AND {0} is equal to {2}: {3}", x, zOR, zAND, x == zOR & x == zAND);
			Console.WriteLine("{0} is equal to {1} AND {0} is equal to {2}: {3}", x, zOR, zAND, x == zOR & x == zAND);

			Console.ReadLine();
		}
	}
}

Open in new window

Which produces the following output -Capture.JPG
The benefit to using || and/or && is that they are short-circuited operations.  If, and only if, the logical equation can be answered by evaluating the left-hand side, then there is no need to evaluate the right-hand side.

So:

true && false evaluates both sides since the logical equation cannot be answered by evaluating the left-hand side only; whereas false && true evaluates the left-hand side only as the equation is answered by the left-hand side operand.  In either case, the same answer, false, is given.

-saige-
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.