root/Code/oMaE/oMaE/MiniGames/FSM.cs @ 104

Revision 104, 8.1 KB (checked in by acarter, 2 years ago)

FSM now loads for serializer

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Microsoft.Xna.Framework;
6using Microsoft.Xna.Framework.Audio;
7using Microsoft.Xna.Framework.Content;
8using Microsoft.Xna.Framework.GamerServices;
9using Microsoft.Xna.Framework.Graphics;
10using Microsoft.Xna.Framework.Input;
11using Microsoft.Xna.Framework.Media;
12using oMaE.Widgets;
13using Serializables;
14
15namespace oMaE.MiniGames
16{
17    /// <summary>
18    /// The finite state machine minigame
19    /// </summary>
20    public class FSM : MiniGame
21    {
22        private class Transition : GameObject
23        {
24            public Color Color;
25            public Vector2 Location;
26            public CompassSelector NextDirection;
27            public DigitSelect NextState;
28            private int states;
29            public Transition(Color Color, Vector2 Location, int states)
30            {
31                this.Color = Color;
32                this.Location = Location;
33                this.states = states;
34            }
35            public override void Initialize()
36            {
37                NextDirection = new CompassSelector(new Rectangle((int)Location.X + 75, (int)Location.Y, 50, 50));
38                children.Add(NextDirection);
39                NextState = new DigitSelect(new Rectangle((int)Location.X + 150, (int)Location.Y, 50, 50), states, 0);
40                children.Add(NextState);
41                base.Initialize();
42            }
43            public override void Draw(Screen2D screen)
44            {
45                screen.FillRectangle(new Rectangle((int)Location.X, (int)Location.Y, 50, 50), Color.White);
46                screen.FillRectangle(new Rectangle((int)Location.X + 10, (int)Location.Y + 10, 30, 30), Color);
47                base.Draw();
48            }
49        }
50
51        private static long DELAY = 3000;
52
53        private int states;
54        private string[] board;
55        private Point start = new Point(0, 0);
56
57        private long timer = 0;
58        private List<Vector3> Path = new List<Vector3>();
59        private int currentEdge { get { return (int) (timer / DELAY); } }
60        private int percentAcross { get { return (int) (timer % DELAY); } }
61        private Color[] colors;
62        private Transition[][] transitions;
63        private int height, width;
64        public FSM(FSMGame game) : base(game)
65        {
66            board = game.Board;
67            height = board.Count();
68            width = 0;
69            foreach (string line in board)
70                if (line.Length > width)
71                    width = line.Length;
72            start = new Point(game.Start[0], game.Start[1]);
73            states = game.States;
74            colors = new Color[game.Colors.Length];
75            for (int i = 0; i < colors.Length; ++i)
76                colors[i] = new Color(game.Colors[i][0], game.Colors[i][1], game.Colors[i][2]);
77        }
78        public override void Initialize()
79        {
80            transitions = new Transition[states][];
81            for(int i = 0; i < states; ++i)
82            {
83                transitions[i] = new Transition[colors.Length];
84                for (int j = 0; j < colors.Length; ++j)
85                {
86                    transitions[i][j] = new Transition(colors[j], new Vector2(100 + 250 * i, 50 + 75 * j), states);
87                    children.Add(transitions[i][j]);
88                }
89            }
90            Path.Add(new Vector3(start.X, start.Y, 0));
91            base.Initialize();
92        }
93        public override void Update(GameState gameState)
94        {
95            timer += gameState.EllapsedMilliseconds;
96            if (timer >= (Path.Count - 1) * DELAY)
97            {
98                timer = (Path.Count - 1) * DELAY;
99                timer = DELAY * Path.FindIndex(o => o == Path[currentEdge]);
100            }
101            base.Update(gameState);
102        }
103        public override bool Correct
104        {
105            get
106            {
107                Path = new List<Vector3>();
108                Vector3 loc = new Vector3(start.X, start.Y, 0);
109                while (true)
110                {
111                    Path.Add(loc);
112                    if (loc.Y < 0 || loc.Y >= board.Length || loc.X < 0 || loc.X >= board[(int)loc.Y].Length)
113                        return false;
114                    switch (board[(int)loc.Y][(int)loc.X])
115                    {
116                        case '!':
117                            return true;
118                        case 'X':
119                            return false;
120                        default:
121                            int val = board[(int)loc.Y][(int)loc.X] - '0';
122                            switch (transitions[(int)loc.Z][val].NextDirection.Value)
123                            {
124                                case CompassSelector.Direction.NORTH:
125                                    loc = new Vector3(loc.X, loc.Y - 1, transitions[(int)loc.Z][val].NextState.Value);
126                                    break;
127                                case CompassSelector.Direction.SOUTH:
128                                    loc = new Vector3(loc.X, loc.Y + 1, transitions[(int)loc.Z][val].NextState.Value);
129                                    break;
130                                case CompassSelector.Direction.EAST:
131                                    loc = new Vector3(loc.X + 1, loc.Y, transitions[(int)loc.Z][val].NextState.Value);
132                                    break;
133                                case CompassSelector.Direction.WEST:
134                                    loc = new Vector3(loc.X - 1, loc.Y, transitions[(int)loc.Z][val].NextState.Value);
135                                    break;
136                            }
137                            break;
138                    }
139                    if (Path.Contains(loc))
140                    {
141                        Path.Add(loc);
142                        return false;
143                    }
144                }
145            }
146        }
147        public override void Draw(Screen2D screen)
148        {
149            screen.FillRectangle(new Rectangle(100, 300, 25 * (width + 2), 25 * (height + 2)), Color.Black);
150            for (int i = 0; i < board.Length; ++i)
151            {
152                for (int j = 0; j < board[i].Length; ++j)
153                {
154                    Color square = Color.Black;
155                    switch (board[i][j])
156                    {
157                        case '0':
158                            square = colors[0];
159                            break;
160                        case '1':
161                            square = colors[1];
162                            break;
163                        case '2':
164                            square = colors[2];
165                            break;
166                        case '!':
167                            square = Color.White;
168                            break;
169                        default:
170                            square = Color.Black;
171                            break;
172                    }
173                    screen.FillRectangle(new Rectangle(125 + 25 * j, 325 + 25 * i, 25, 25), square);
174                }
175            }
176            screen.DrawText("0", new Vector2(137.5f + 25 * start.X, 337.5f + 25 * start.Y), TextHorizontal.CENTERED, TextVertical.CENTERED, Color.White);
177            if (percentAcross != 0)
178            {
179                Vector2 loc = new Vector2(137.5f + 25 * (percentAcross * Path[currentEdge+1].X + Path[currentEdge].X * (DELAY - percentAcross)) / DELAY,
180                                337.5f + 25 * (percentAcross * Path[currentEdge+1].Y + Path[currentEdge].Y * (DELAY - percentAcross)) / DELAY);
181                screen.DrawText(Path[currentEdge].Z.ToString(), loc, TextHorizontal.CENTERED, TextVertical.CENTERED, Color.Black);
182            }
183            else
184            {
185                screen.DrawText(Path[currentEdge].Z.ToString(),
186                        new Vector2(137.5f + 25 * Path[currentEdge].X, 337.5f + 25 * Path[currentEdge].Y),
187                        TextHorizontal.CENTERED, TextVertical.CENTERED, Color.Black);
188            }
189            base.Draw(screen);
190        }
191    }
192}
Note: See TracBrowser for help on using the browser.