]> Dogcows Code - chaz/carfire/blobdiff - Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs
initial upload
[chaz/carfire] / Project06 / CS 3505 Project 06 / CS 3505 Project 06 / CS 3505 / TestHarness.cs
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs
new file mode 100644 (file)
index 0000000..76bc066
--- /dev/null
@@ -0,0 +1,416 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Input;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CS_3505_Project_06.CS_3505\r
+{\r
+    // Everything in objects built from this class represent the critical game state\r
+    public class GameState\r
+    {\r
+        public long frameNumber;\r
+\r
+        private long checksum;\r
+        public long Checksum { get { return checksum; } }\r
+\r
+        public bool[] isGameOver;\r
+        public bool[] isTerminated;\r
+\r
+        // Since this is not a game, I'll just keep track of the user inputs as the game state.\r
+\r
+        public int[] mouseLocationX;\r
+        public int[] mouseLocationY;\r
+        public bool[] mouseButton;\r
+        public List<Keys>[] keysDown;\r
+        public int[] keypressCount;\r
+\r
+        public long elapsedTime;\r
+\r
+        /* Constructor */\r
+        public GameState()\r
+        {\r
+            frameNumber = 0;\r
+            checksum = 0;\r
+\r
+            isGameOver = new bool[4];\r
+            isTerminated = new bool[4];\r
+\r
+            mouseLocationX = new int[4];\r
+            mouseLocationY = new int[4];\r
+            mouseButton = new bool[4];\r
+            keysDown = new List<Keys>[4];\r
+            for (int i = 0; i < 4; i++)\r
+                keysDown[i] = new List<Keys>();\r
+            keypressCount = new int[4];\r
+\r
+            elapsedTime = 0;\r
+\r
+            checksum = 0;\r
+        }\r
+\r
+        /* The game engine! */\r
+        public void advanceFrame(NextInputs inputs, long milliseconds)\r
+        {\r
+            // Advance frame number\r
+            frameNumber++;\r
+\r
+            // Advance game - for the test harness, just record statistics and input states.\r
+\r
+            elapsedTime += milliseconds;\r
+\r
+            for (int player = 0; player < 4; player++)\r
+            {\r
+                if (isGameOver[player])\r
+                    continue;\r
+\r
+                if (inputs.mousePressedChanged[player])\r
+                    mouseButton[player] = inputs.mousePressed[player];\r
+\r
+                if (inputs.mouseLocationChanged[player])\r
+                {\r
+                    mouseLocationX[player] = inputs.mouseLocationX[player];\r
+                    mouseLocationY[player] = inputs.mouseLocationY[player];\r
+                }\r
+\r
+                foreach (Keys k in inputs.keysPressed[player])\r
+                    if (!keysDown[player].Contains(k))\r
+                    {\r
+                        keysDown[player].Add(k);\r
+                        keypressCount[player]++;\r
+                    }\r
+\r
+                foreach (Keys k in inputs.keysReleased[player])\r
+                        keysDown[player].Remove(k);                 \r
+\r
+                // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate\r
+\r
+                if (inputs.mousePressed[player])\r
+                    for (int p = 0; p < 4; p++)\r
+                    {\r
+                        int x = 200 * p + 10;\r
+                        int y = 220;\r
+\r
+                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
+                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
+                        {\r
+                            isGameOver[p] = true;\r
+                        }\r
+                        y += 25;\r
+                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
+                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
+                        {\r
+                            isGameOver[p] = true;\r
+                            isTerminated[p] = true;\r
+                        }\r
+                    }\r
+\r
+            }\r
+\r
+            // Advance the checksum.\r
+\r
+            computeChecksum();\r
+            \r
+        }\r
+\r
+        /* Just hash the values */\r
+        private long computeChecksum()\r
+        {\r
+            checksum += frameNumber;\r
+            for (int i = 0; i < 4; i++)\r
+            {\r
+                checksum = checksum + keypressCount[i];\r
+                checksum = checksum * 3 + (isGameOver[i] ? 1 : 2);\r
+                checksum = checksum * 3 + (isTerminated[i] ? 1 : 2);\r
+                foreach (Keys k in keysDown[i])\r
+                    checksum = checksum * 257 + (int) k;\r
+                checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375;\r
+                checksum = checksum * 3 + (mouseButton[i] ? 1 : 2);\r
+\r
+            }\r
+            checksum += elapsedTime;\r
+\r
+            return checksum;\r
+        }\r
+    }\r
+\r
+    // This class encapsulates inputs from the players.\r
+    public class NextInputs\r
+    {\r
+        public List<Keys>[] keysPressed;\r
+        public List<Keys>[] keysReleased;\r
+        public int[] mouseLocationX;\r
+        public int[] mouseLocationY;\r
+        public bool[] mouseLocationChanged;\r
+        public bool[] mousePressed;\r
+        public bool[] mousePressedChanged;\r
+\r
+        public NextInputs()\r
+        {\r
+            keysPressed = new List<Keys>[4];\r
+            keysReleased = new List<Keys>[4];\r
+            mouseLocationX = new int[4];\r
+            mouseLocationY = new int[4];\r
+            mouseLocationChanged = new bool[4];\r
+            mousePressed = new bool[4];\r
+            mousePressedChanged = new bool[4];\r
+            for (int i = 0; i < 4; i++)\r
+                keysPressed[i] = new List<Keys>();\r
+            for (int i = 0; i < 4; i++)\r
+                keysReleased[i] = new List<Keys>();\r
+        }\r
+    }\r
+\r
+    public class TestHarness : IDeterministicGame\r
+    {\r
+        GameState state;\r
+        NextInputs inputs;\r
+        Object[] playerIdentifiers;\r
+        int thisPlayerID;\r
+\r
+        // Instance variables here contribute to the display, but not the game state\r
+\r
+        Texture2D crosshair;\r
+        SpriteFont font;\r
+\r
+        // Constructor\r
+\r
+        public TestHarness()\r
+        {\r
+            playerIdentifiers = new Object[4];\r
+        }\r
+\r
+        // Helper methods\r
+\r
+        private int idPlayer(Object playerIdentifier)\r
+        {\r
+            for (int i = 0; i < playerIdentifiers.Length; i++)\r
+                if (playerIdentifiers[i] == playerIdentifier)\r
+                    return i;\r
+            throw new Exception("Illegal player identifier" + playerIdentifier);\r
+        }\r
+\r
+        // Implementation of the DeterministicGame interface\r
+        #region IDeterministicGame Members\r
+\r
+        public void LoadContent(ContentManager contentManager)\r
+        {\r
+            crosshair = contentManager.Load<Texture2D>("CS 3505/Crosshair");\r
+            font = contentManager.Load<SpriteFont>("CS 3505/GameFont");\r
+        }\r
+\r
+        public void UnloadContent()\r
+        {\r
+            // Nothing to do - the content manager will take care of it.\r
+        }\r
+\r
+        public Vector2 PreferredScreenSize\r
+        {\r
+            get { return new Vector2(800, 600); }\r
+        }\r
+\r
+        public int MinimumSupportedPlayers\r
+        {\r
+            get { return 4; }\r
+        }\r
+\r
+        public int MaximumSupportedPlayers\r
+        {\r
+            get { return 4; }\r
+        }\r
+\r
+        public void ResetGame(Object[] playerIdentifiers, Object thisPlayer)\r
+        {\r
+            if (playerIdentifiers.Length != 4)\r
+                throw new Exception("This game requires four players.");\r
+\r
+            // Copy the player identifiers - do not rely on the array parameter not changing.\r
+\r
+            for (int i = 0; i < 4; i++)\r
+                this.playerIdentifiers[i] = playerIdentifiers[i];\r
+\r
+            // Create new game state and inputs objects.\r
+\r
+            state = new GameState();\r
+            inputs = new NextInputs();\r
+\r
+            // Record 'this' player.\r
+\r
+            this.thisPlayerID = idPlayer(thisPlayer);\r
+        }\r
+\r
+        public long CurrentFrameNumber\r
+        {\r
+             get { return state.frameNumber; }\r
+        }\r
+\r
+        public long CurrentChecksum\r
+        {\r
+            get { return state.Checksum; }\r
+        }\r
+\r
+        public void ApplyKeyInput(Object playerIdentifier, Keys key, bool isKeyPressed)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+\r
+            if (isKeyPressed && !inputs.keysPressed[player].Contains(key))\r
+                inputs.keysPressed[player].Add(key);\r
+\r
+            if (!isKeyPressed && !inputs.keysReleased[player].Contains(key))\r
+                inputs.keysReleased[player].Add(key);\r
+        }\r
+\r
+        public void ApplyMouseLocationInput(Object playerIdentifier, int x, int y)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            inputs.mouseLocationX[player] = x;\r
+            inputs.mouseLocationY[player] = y;\r
+            inputs.mouseLocationChanged[player] = true;\r
+        }\r
+\r
+        public void ApplyMouseButtonInput(Object playerIdentifier, bool isButtonPressed)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            inputs.mousePressed[player] = isButtonPressed;\r
+            inputs.mousePressedChanged[player] = true;\r
+        }\r
+\r
+        public bool IsGameOver(Object playerIdentifier)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            return state.isGameOver[player] ;\r
+        }\r
+\r
+        public bool IsTerminated(object playerIdentifier)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            return state.isTerminated[player];\r
+        }\r
+\r
+        public long Update(TimeSpan elapsedTime)\r
+        {\r
+            state.advanceFrame(inputs, elapsedTime.Milliseconds);  // Apply the inputs, advance game state.\r
+\r
+            inputs = new NextInputs();  // Start with inputs cleared on the next frame.\r
+\r
+            return state.frameNumber;\r
+        }\r
+\r
+        public long Draw(SpriteBatch spriteBatch)\r
+        {\r
+            centerString(spriteBatch, Color.White, "CS 3505 - Software Practice 2", 0, 800, 0);\r
+            centerString(spriteBatch, Color.White, "Test Harness", 0, 800, 25);\r
+            centerString(spriteBatch, Color.White, "Debug output", 0, 800, 50);\r
+\r
+            nameIntPair(spriteBatch, Color.White, "Frame:", state.frameNumber, 10, 150, 100);\r
+            nameHexPair(spriteBatch, Color.White, "Checksum:", state.Checksum, 215, 515, 100);\r
+            nameDecPair(spriteBatch, Color.White, "Elapsed Time:", state.elapsedTime / 1000.0f, 570, 790, 100);\r
+\r
+            printPlayer(spriteBatch, Color.Turquoise, 0,  10, 190, 170);\r
+            printPlayer(spriteBatch, Color.Wheat,     1, 210, 390, 170);\r
+            printPlayer(spriteBatch, Color.Tomato,    2, 410, 590, 170);\r
+            printPlayer(spriteBatch, Color.Violet,    3, 610, 790, 170);\r
+\r
+            if (!state.isGameOver[0])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[0] - 5, state.mouseLocationY[0] - 5), Color.Turquoise);\r
+            if (!state.isGameOver[1])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[1] - 5, state.mouseLocationY[1] - 5), Color.Wheat);\r
+            if (!state.isGameOver[2])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[2] - 5, state.mouseLocationY[2] - 5), Color.Tomato);\r
+            if (!state.isGameOver[3])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[3] - 5, state.mouseLocationY[3] - 5), Color.Violet);\r
+\r
+            spriteBatch.Draw(crosshair, new Vector2(Mouse.GetState().X - 5, Mouse.GetState().Y - 5), Color.White);\r
+\r
+            return state.frameNumber;\r
+        }\r
+\r
+        #endregion\r
+\r
+        void printPlayer(SpriteBatch spriteBatch, Color c, int player, float left, float right, float top)\r
+        {\r
+            leftJustify(spriteBatch, c, String.Format("Player {0}", player+1), left, top);\r
+            top += 10;\r
+            leftJustify(spriteBatch, c, "_________", left, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "[X] Game Over", state.isGameOver[player]?1:0, left, right, top);\r
+            top += 25;\r
+            nameIntPair(spriteBatch, c, "[X] Terminated", state.isTerminated[player] ? 1 : 0, left, right, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "Mouse X", (int)state.mouseLocationX[player], left, right, top);\r
+            top += 25;\r
+            nameIntPair(spriteBatch, c, "Mouse Y", (int)state.mouseLocationY[player], left, right, top);\r
+            top += 40;\r
+            leftJustify(spriteBatch, c, "Mouse", left, top);\r
+            rightJustify(spriteBatch, c, state.mouseButton[player]?"Pressed":"Released", right, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "Key count", (int)state.keypressCount[player], left, right, top);\r
+            top += 25;\r
+            leftJustify(spriteBatch, c, "Keys", left, top);\r
+            if (state.keysDown[player].Count == 0)\r
+                rightJustify(spriteBatch, c, "None", right, top);\r
+            else\r
+                foreach (Keys k in state.keysDown[player])\r
+                {\r
+                    rightJustify(spriteBatch, c, k.ToString(), right, top);\r
+                    top += 25;\r
+                }\r
+\r
+        }\r
+\r
+        void centerString(SpriteBatch spriteBatch, Color c, String s, float left, float right, float top)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = left + (right-left - v.X) / 2;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void centerString(SpriteBatch spriteBatch, Color c, String s, Rectangle r)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = r.Left + (r.Width - v.X) / 2;\r
+            float y = r.Top + (r.Height - v.Y) / 2;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void leftJustify(SpriteBatch spriteBatch, Color c, String s, float left, float top)\r
+        {\r
+            float x = left;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void rightJustify(SpriteBatch spriteBatch, Color c, String s, float right, float top)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = right - v.X;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void nameDecPair(SpriteBatch spriteBatch, Color c, String name, float number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0:.00}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+\r
+        void nameIntPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+\r
+        void nameHexPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0:x}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+    }\r
+}\r
This page took 0.029713 seconds and 4 git commands to generate.