context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.IO;
  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.Media;
  
  namespace HuntTheWumpus
  {
      /// <summary>
      /// This is a game component that implements IUpdateable
      /// </summary>
      /// 
      public enum State 
      {
          MOVING,
          SWITCHING,
          TRANSPORTED,
          QUESTIONING,
          ADJUSTING,
          SHOOTING
      }
  
      public class GameControl : Microsoft.Xna.Framework.GameComponent
      {
          public List<Sprite> spriteList = new List<Sprite>();
          // Add a SpriteFont object to display text
          SpriteFont consolas;
          Vector2 fontPos;
          Trivia.Question[] questions;
          int triviaResults = 0;
          int triviaResultsNeeded = 0;
          bool triviaSucceeded;
          int triviaCount, triviaMax;
          Func<bool> triviaResolve;
          public Button[] buttons;
          bool winning = false;
  
          public static Point[] vertices = { new Point(4, 256), new Point(130, 38), new Point(380, 38), new Point(509, 256), new Point(380, 474), new Point(130, 474)};
          public static List<RoomImage> roomImages;
          public static List<Sprite> displaySprites;
          public static Game game;
          public static Cave cave;
          public static Player player = new Player(game);
  
          public ScoreHandler scoreHandler;
  
          bool firingResolved = false;
          bool firing = false;
  
          List<Sprite> hitList = new List<Sprite>();
          public State state = State.MOVING;
          Vector2 moveVector;
          int moveCounter;
          public ScoreHandler.Score score = new ScoreHandler.Score();
  
          Texture2D background;
          Texture2D introImage;
          Texture2D highscoreImage;
          Texture2D selectionImage1;
          Texture2D selectionImage2;
          Texture2D selectionImage3;
          Texture2D selectionImage;
          Texture2D HUD;
          Texture2D arrowOverlay;
          public Texture2D arrow;
          public int roomSwitch;
          public Vector2 transportDelta;
  
          public byte currentSelectionBox = 0;
  
          public SpriteManager spriteManager;
  
          bool oldKeyboardState;
          bool currentKeyboardState;
  
          bool oldKeyboardStateUp;
          bool currentKeyboardStateUp;
  
          public static Trivia trivia = new Trivia();
  
          // Variables for adjacent rooms and their contents
          bool wumpus = false;
          bool pit = false;
          bool bat = false;
  
          public string arrowCount;
          public string hint;
          public string triviaString, answer1, answer2, answer3, answer4;
  
          public static bool wumpusDefeated;
  
          // GameControl class
          public GameControl(Game game)
              : base(game)
          {
              // TODO: Construct any child components here
          
          }
  
          /// <summary>
          /// Allows the game component to perform any initiali zation it needs to before starting
          /// to run.  This is where it can query for any required services and load content.
          /// </summary>
          public override void Initialize()
          {
              // TODO: Add your initialization code here
  
              GUIStubb graphicsInterface = new GUIStubb();
              spriteManager = new SpriteManager(game, player);
              roomImages = new List<RoomImage>();
              displaySprites = new List<Sprite>();
              cave = new Cave("test.cave");
              Vector2 _position = new Vector2();
  
              buttons = new Button[4];
              buttons[0] = new Button(new Vector2(5, 620), 0, game);
              buttons[1] = new Button(new Vector2(5, 655), 1, game);
              buttons[2] = new Button(new Vector2(5, 690), 2, game);
              buttons[3] = new Button(new Vector2(5, 725), 3, game);
  
  
              for (int x = 0; x < cave.Width; x++) {
                  for (int y = 0; y < cave.Height; y++) {
                      _position.X = (x * 380);
                      _position.Y = (y * 438) - ((x % 2) * 219);
                      cave.Rooms[x,y].image = new RoomImage(_position,"Images/hex","Images/hex2",game);
                      cave.Rooms[x, y].image.setExits(cave.Rooms[x, y].Exits);
                      roomImages.Add(cave.Rooms[x, y].image);
                      bool w,b,p;
                      cave.GetAdjacent(x,y,out w, out b, out p);
                      if(w)
                      {
                         cave.Rooms[x, y].image.nearWumpus = true;
                      }
                      if (cave.Rooms[x, y].hasBats)
                      {
                          cave.Rooms[x, y].image.bat = true;
                          cave.Rooms[x, y].image.resolved = false;
                      }
                      if (cave.Rooms[x, y].hasPit)
                      {
                          cave.Rooms[x, y].image.pit = true;
                          cave.Rooms[x, y].image.resolved = false;
                      }
                      if (cave.Rooms[x, y].hasWumpus)
                      {
                          cave.Rooms[x,y].image.wumpus = true;
                          cave.Rooms[x, y].image.resolved = false;
  
                      }
                  }
              }
              hint = "";
              cave.movePlayer(0, 0);
              cave.Rooms[cave.locationPlayer.X, cave.locationPlayer.Y].image.revealed = true;
              cave.Rooms[cave.locationPlayer.X, cave.locationPlayer.Y].image.currentRoom = true;
              base.Initialize();
  
              if (File.Exists(".user-config"))
                  using (var sr = new StreamReader(".user-config"))
                      score.Name = sr.ReadToEnd();
              else
              {
                  score.Name = "User";
                  using (var sw = new StreamWriter(".user-config"))
                      sw.Write("User");
              }
          }
  
          /// <summary>
          /// Allows the game component to update itself.
          /// 
          /// Updates game objects
          /// Sends objects to be drawn to GUI which then draws them
          /// </summary>
          /// <param name="gameTime">Provides a snapshot of timing values.</param>
          public override void Update(GameTime gameTime)
          {
              // TODO: Add your update code here
  
              hint = (cave.locationPlayer.X.ToString() + ", " + cave.locationPlayer.Y.ToString()) ;
              #region Moving State
              if (state == State.MOVING) {
                  player.speed.X = 0;
                  player.speed.Y = 0;
  
                  
                  if (Keyboard.GetState().IsKeyDown(Keys.Left) || Input.isKeyDown(Keys.A))
                      player.speed.X -= 3;
  
                  if (Input.isKeyDown(Keys.Right) || Input.isKeyDown(Keys.D))
                      player.speed.X += 3;
                  
                  if (Input.isKeyDown(Keys.Up) || Input.isKeyDown(Keys.W))
                      player.speed.Y -= 3;
  
                  if (Input.isKeyDown(Keys.Down) || Input.isKeyDown(Keys.S))
                      player.speed.Y += 3;
  
                  if (Input.isKeyPressed(Keys.F) && player.arrows > 0) {
                      state = State.ADJUSTING;
                      moveCounter = 0;
                      moveVector = new Vector2(240) - player.position;
                  }
                  if (Input.isKeyPressed(Keys.B)) {
                      BuyArrow();
                  }
  
                  // Update all the game objects
                  // Send these updates to GUI to be drawn
                  player.position += player.speed;
  
                  //Glad you asked. It resolves collisions with walls in a 95% reliable way
                  //If collisions are with a doorway in the current room, there can be code to switch rooms
  
  
                  Point lastpoint;
                  Point thispoint;
  
                  thispoint = vertices[5];
                  for (int i = 0; i < 6; i++) {
                      lastpoint = new Point(thispoint.X, thispoint.Y);
                      thispoint = vertices[i];
  
                      if (player.checkCollision(lastpoint, thispoint)) {
                          if (cave.Rooms[cave.locationPlayer.X, cave.locationPlayer.Y].image.edgeDraws[i] == true)
                              player.resolveCollision(lastpoint, thispoint);
                          else if (cave.Rooms[cave.locationPlayer.X, cave.locationPlayer.Y].image.edgeDraws[i] != true) {
                              state = State.SWITCHING;
                              score.Turns++;
                              moveVector = new Vector2(vertices[i].X - vertices[(i + 2) % 6].X, vertices[i].Y - vertices[(i + 2) % 6].Y) * -1;
                              moveCounter = 0;
                              roomSwitch = i;
                              Console.WriteLine(i);
                              cave.locationPlayer.image.currentRoom = false;
                          }
                      }
                  }
  
              }
              #endregion
              #region Switching State
              else if (state == State.SWITCHING) {
                      moveCounter++;
                      if (moveCounter >= 30) {
                          state = State.MOVING;
                          moveCounter = 0;
                          int dy = cave.locationPlayer.Y;
                          int dx = cave.locationPlayer.X;
                          switch (roomSwitch) {
                              case 0:                            
                                  if (cave.locationPlayer.X % 2 == 0) {
                                      dx = cave.locationPlayer.X - 1;
                                      if(dx < 0){
                                          dx = cave.Width - 1;
                                      }
                                      dy = cave.locationPlayer.Y + 1;
                                      if (dy > cave.Height - 1) {
                                          dy = 0;
                                      }
                                  }
                                  else {
                                      dx = cave.locationPlayer.X - 1;
                                      if (dx < 0) {
                                          dx = cave.Width - 1;
                                      }
                                      dy = cave.locationPlayer.Y;
                                  }
                                  break;
                              case 1:
  
                                  if (cave.locationPlayer.X % 2 == 1) {
                                      dx = cave.locationPlayer.X - 1;
                                      if (dx < 0) {
                                          dx = cave.Width - 1;
                                      }
                                      dy = cave.locationPlayer.Y - 1;
                                      if (dy < 0) {
                                          dy = cave.Height - 1;
                                      }
                                  }
                                  else {
                                      dx = cave.locationPlayer.X - 1;
                                      if (dx < 0) {
                                          dx = cave.Width - 1;
                                      }
                                      dy = cave.locationPlayer.Y;
                                  }
                                  break;
                              case 2:
  
                                  dx = cave.locationPlayer.X;
                                  dy = cave.locationPlayer.Y - 1;
  
gt:                                 if (dy < 0) {