So I'm working on a Windows Phone app using XNA and I'm at my wit's end with it.

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.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace WindowsPhoneGame1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        int[,] map = new int[10,10];
        int[,] blankMap = new int[10, 10];
        int[] validmove1 = new int[2];
        int[] validmove2 = new int[2];
        int[] validmove3 = new int[2];
        int[] validmove4 = new int[2];
        int[] lastmove = new int[2];

        int touchx;
        int touchy;

        int moves;

        string outputString;

        Vector2 drawbuffer;
        Vector2 FontPos1;

        Texture2D blank;
        Texture2D cross;
        Texture2D nought;
        Texture2D wall;
        SpriteFont Font1;

            void resetMap()
    {
        Array.Copy(blankMap,map,100);
        //memcpy(map,resetmap,sizeof map);
        //PlaySound(L"restart.wav", NULL, SND_ASYNC | SND_FILENAME);
    }

            bool checkwin()
        {
            int numnought = 0;

            for (int countline = 0; countline <= 9; countline++)
            {
                for (int count = 0; count <= 9; count++)
                {
                    if (map[countline,count] == 1)
                    {
                        numnought++;
                    }
                }
            }
            if (numnought >= 1)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

            bool canmove()
    {

        int movey = lastmove[0];
        int movex = lastmove[1];
        int[] checkblank = new int[2];
        checkblank[0] = 0;
        checkblank[1] = 0;
        int possmoves = 0;

        if(map[movey+1,movex] == 1)
        {
            possmoves ++;
            validmove1[0] = movey+1;
            validmove1[1] = movex;
        }
        else if(map[movey+1,movex] == 0 && map[movey+2,movex] == 1)
        {
                possmoves ++;
                validmove1[0] = movey+2;
                validmove1[1] = movex;
        }
        else if(map[movey+1,movex] == 2)
        {
            checkblank[0] = movey+1;
            checkblank[1] = movex;
            while(map[checkblank[0],checkblank[1]] == 2)
            {
                checkblank[0] = checkblank[0]++;
                checkblank[1] = checkblank[1];
            }
            if(map[checkblank[0],checkblank[1]] == 1)
            {
                possmoves ++;
                validmove1[0] = checkblank[0];
                validmove1[1] = checkblank[1];
            }
            if(map[checkblank[0]++,checkblank[1]] == 0)
            {
                //possmoves = possmoves;
            }
            if(map[checkblank[0],checkblank[1]] == 3)
            {
                //possmoves = possmoves;
            }
        }

        checkblank[0] = 0;
        checkblank[1] = 0;

        if(map[movey-1,movex] == 1)
        {
            possmoves++;
            validmove2[0] = movey-1;
            validmove2[1] = movex;
        }
        else if(map[movey-1,movex] == 2)
        {
            checkblank[0] = movey-1;
            checkblank[1] = movex;
            while(map[checkblank[0],checkblank[1]] == 2)
            {
                checkblank[0] = checkblank[0]--;
                checkblank[1] = checkblank[1];
            }
            if(map[checkblank[0],checkblank[1]] == 1)
            {
                possmoves ++;
                validmove2[0] = checkblank[0];
                validmove2[1] = checkblank[1];
            }
            if(map[checkblank[0],checkblank[1]] == 0)
            {

            }
            if(map[checkblank[0],checkblank[1]] == 3)
            {

            }
        }
        else if(map[movey-1,movex] == 0 && map[movey-2,movex] == 1)
        {
                possmoves ++;
                validmove2[0] = movey-2;
                validmove2[1] = movex;
        }

        checkblank[0] = 0;
        checkblank[1] = 0;

        if(map[movey,movex+1] == 1)
        {
            possmoves++;
            validmove3[0] = movey;
            validmove3[1] = movex+1;
        }
        else if(map[movey,movex+1] == 2)
        {
            checkblank[0] = movey;
            checkblank[1] = movex+1;
            while(map[checkblank[0],checkblank[1]] == 2)
            {
                checkblank[0] = checkblank[0];
                checkblank[1] = checkblank[1]++;
            }
            if(map[checkblank[0],checkblank[1]] == 1)
            {
                possmoves ++;
                validmove3[0] = checkblank[0];
                validmove3[1] = checkblank[1];
            }
            if(map[checkblank[0],checkblank[1]] == 0)
            {

            }
            if(map[checkblank[0],checkblank[1]] == 3)
            {

            }
        }
        else if(map[movey,movex+1] == 0 && map[movey,movex+2] == 1)
        {
                possmoves ++;
                validmove3[0] = movey;
                validmove3[1] = movex+2;

        }

        checkblank[0] = 0;
        checkblank[1] = 0;

        if(map[movey,movex-1] == 1)
        {
            possmoves++;
            validmove4[0] = movey;
            validmove4[1] = movex-1;
        }
        else if(map[movey,movex-1] == 2)
        {
            checkblank[0] = movey;
            checkblank[1] = movex-1;
            while(map[checkblank[0],checkblank[1]] == 2)
            {
                checkblank[0] = checkblank[0];
                checkblank[1] = checkblank[1]--;
            }
            if(map[checkblank[0],checkblank[1]] == 1)
            {
                possmoves ++;
                validmove4[0] = checkblank[0];
                validmove4[1] = checkblank[1];
            }
            if(map[checkblank[0],checkblank[1]] == 0)
            {

            }
            if(map[checkblank[0],checkblank[1]] == 3)
            {

            }
        }
        else if(map[movey,movex-1] == 0 && map[movey,movex-2] == 1)
        {
                possmoves ++;
                validmove4[0] = movey;
                validmove4[1] = movex-2;
        }   

        checkblank[0] = 0;
        checkblank[1] = 0;

        if(possmoves >= 1)
        {
            //cout << endl << "POSSIBLE MOVES: " << possmoves << endl << endl;
            return true;
        }
        else
        {
            return false;
        }
    }

        void redraw(SpriteBatch spritebatch)
        {
            spritebatch.Begin();
            int drawbufferx = 0;
            int drawbuffery = 0;
            for (int countline = 0; countline <= 9; countline++)
            {
                for (int count = 0; count <= 9; count++)
                {
                    if (map[countline,count] == 1)
                    {
                        drawbuffer.X = drawbufferx;
                        drawbuffer.Y = drawbuffery;
                        spritebatch.Draw(cross, drawbuffer, Color.White);// al_draw_bitmap(cross, drawbufferx, drawbuffery, 0);
                        drawbufferx += 50;
                    }
                    else if (map[countline,count] == 2)
                    {
                        drawbuffer.X = drawbufferx;
                        drawbuffer.Y = drawbuffery;
                        spritebatch.Draw(blank, drawbuffer, Color.White);
                        //al_draw_bitmap(nought, drawbufferx, drawbuffery, 0);
                        drawbufferx += 50;
                    }
                    else if (map[countline,count] == 3)
                    {
                        drawbuffer.X = drawbufferx;
                        drawbuffer.Y = drawbuffery;
                        spritebatch.Draw(wall, drawbuffer, Color.White);
                        //al_draw_bitmap(wall, drawbufferx, drawbuffery, 0);
                        drawbufferx += 50;
                    }
                    else if (map[countline,count] == 0)
                    {
                        drawbuffer.X = drawbufferx;
                        drawbuffer.Y = drawbuffery;
                        spritebatch.Draw(nought, drawbuffer, Color.White);
                        //al_draw_bitmap(blank, drawbufferx, drawbuffery, 0);
                        drawbufferx += 50;
                    }
                }
                drawbufferx = 0;
                drawbuffery += 50;
                //al_set_target_bitmap(al_get_backbuffer(display));
                //al_draw_bitmap(board,0,0,0);
                //al_flip_display();
                //Sleep(10);
                //al_set_target_bitmap(board);
            }
            drawbufferx = 0;
            drawbuffery = 0;
            Vector2 FontOrigin = Font1.MeasureString(outputString);
            // Draw the string
            spriteBatch.DrawString(Font1, outputString, FontPos1, Color.White,
                0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);

            spritebatch.End();
        }

        bool validmove(int clicky, int clickx)
        {
            if (clicky == validmove1[0] && clickx == validmove1[1])
            {
                return true;
            }
            else if (clicky == validmove2[0] && clickx == validmove2[1])
            {
                return true;
            }
            else if (clicky == validmove3[0] && clickx == validmove3[1])
            {
                return true;
            }
            else if (clicky == validmove4[0] && clickx == validmove4[1])
            {
                //Debug.WriteLine(string.Format(“Touched! ID: {0}, state: {1} at {2}”, location.Id,   location.State, location.Position));
                return true;
            }
            else
            {
                return false;
            }
        }

        void randommap()
        {
        Random rand = new Random();
        lastmove[0] = 0;
        lastmove[1] = 1;
        for(int countline = 0; countline <= 9; countline++)
        {
            for(int count = 0;count <= 9; count++)
            {
                int random = 0;
                random = rand.Next(2);
                map[countline,count] = random;
            }
        }
        for(int forceborder = 0; forceborder <= 9; forceborder++)
        {
            map[forceborder,0] = 3;
            map[forceborder,9] = 3;
            map[0,forceborder] = 3;
            map[9,forceborder] = 3;

        }
       // map[1, 1] = 1;
        //memcpy(resetmap,map,sizeof resetmap);
        }
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        /// <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
            randommap();
            moves = 0;
            lastmove[0] = 0;
            lastmove[1] = 0;
            outputString = "null";
            base.Initialize();
            TouchPanel.EnabledGestures = GestureType.Tap;
        }

        /// <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);

            blank = Content.Load<Texture2D>("blank");
            cross = Content.Load<Texture2D>("cross");
            nought = Content.Load<Texture2D>("nought");
            wall = Content.Load<Texture2D>("wall");
            Font1 = Content.Load<SpriteFont>("SpriteFont1");
            FontPos1 = new Vector2(550, 50);

            // 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>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();


            // TODO: Add your update logic here

             // check whether gestures are available
            foreach (TouchLocation location in TouchPanel.GetState())//while (TouchPanel.IsGestureAvailable)
            {
                // read the next gesture
                //var gesture = TouchPanel.ReadGesture();

                // has the user tapped the screen?
                //if (gesture.GestureType == GestureType.Tap)
                //{
                    touchx = (int)location.Position.X/50;
                    touchy = (int)location.Position.Y/50;

                    outputString = "touch";

                    if (location.Position.X < 500 && location.Position.Y < 500 && map[touchy,touchx] == 1)
                    {
                        if (validmove(touchy, touchx) == true || moves == 0)
                        {
                            map[touchy, touchx] = 0;
                            //PlaySound(L"audio\\bleep.wav", NULL, SND_ASYNC | SND_FILENAME);
                            //seconds --;
                            if (moves >= 1)
                            {
                                map[lastmove[0], lastmove[1]] = 0;
                            }
                            lastmove[0] = touchy;
                            lastmove[1] = touchx;
                            moves++;
                            //score += 20;
                            //printscore();
                        }
                        else
                        {
                            //cout << endl << endl << "You cannot move there" << endl << endl;
                        }
                        redraw(this.spriteBatch);
                        //al_draw_bitmap(pass,500,300,0);
                        //al_draw_bitmap(quit,500,100,0);
                        //al_flip_display();
                    }

            if(canmove() == false)
            {
                //cout << endl << endl << "YOU LOSE" << endl << endl;
                //PlaySound(L"audio\\fail.wav", NULL, SND_ASYNC | SND_FILENAME);
                //Sleep(2000);
                outputString = "lose";
                resetMap();
                randommap();
                moves = 0;
                lastmove[0] = 0;
                lastmove[1] = 0;
            }
            else if (checkwin() == true)
            {
                //cout << endl << endl << "YOU WIN!";
                //PlaySound(L"audio\\win.wav", NULL, SND_ASYNC | SND_FILENAME);
                //Sleep(2000);
                //system("CLS");
                outputString = "win";
                randommap();
                resetMap();
                moves = 0;
                lastmove[0] = 0;
                lastmove[1] = 0;
                //seconds = 240;
                //lowtime = false;
                //score += 500;
                //printscore();
                redraw(this.spriteBatch);
                //al_draw_bitmap(pass,500,300,0);
                //al_draw_bitmap(quit,500,100,0);
                //al_flip_display();
            }
               // }
            }

            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.Black);
            redraw(this.spriteBatch);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}

So the app runs ok. But there are just endless and nonsensical problems with it:

1: In the randommap function, If I try to add 1 to the 'random' integer and then apply it to the array location in 'map', the app is unresponsive when you try to run it for no apparent reason. Not adding 1 works fine. Problem is for the app to work how I want I really need to add 1 to that number.

2: Despite being in the code in a number of places including when a win or loss is found in the update function, the 'lastmove' array never resets. I have no idea why.

3: Since the 'lastmove' array never resets for some reason. If a new map is generated by the 'randommap' function and on the new map there is nowhere you can move from the lastmove position that failed to reset for god only knows what reason, the app crashes and throws up an outofrange exception on this line:

if(map[movey-1,movex] == 1)

Specifically the 1 at the end. Again, this happens for no apparent reason since all the values in that statement are correct.

To make it even more inexplicable, there isn't even a call to that function in the loss handler or the map generator so it seems to just be running that function for fun or something.

I'm completely at a loss to figure out what is wrong. It just seems like random things aren't working for literally no reason.

Can anyone offer any advice as to what is wrong with this thing???

It really looks like you need to think about your structure, or at least improve the clarity of your logic. It seems, for the most part, that the majority of the logic is used to determine possible moves based on a given 10x10 mapping that might have obstacles or something (I didn't read all of it). I re-analyzing the way you look at what it is doing might help clear some of these issues up.

A long time ago I wrote a chess game that needed to understand the board layout in a very simple and fast manner (in order for the AI to determine more moves per turn). My first go at it was terrible. It was really messy coding that was near impossible to follow, and while not being near done took up over 1500 lines of code. After a bit of research I decided to rewrite it with the board being represented by a few 64 bit integers. Every bit in the integer represented a mask on the board (just so happens a chess board is 8x8 made these calculations very simple). There was an integer for each type of piece, another 2 that represented the team of each piece, and another set representing the potential moves of each piece. All of these combined in different ways represented the game state. Simple bitwise arithmetic allowed lightning fast generation of future board states for the AI to anylize. A similar (not necessarily bitwise) approach might be a good idea here.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.