public NeuralThinker(IEnumerable<GameStateMoveAction> moves,
							IEnumerable<GameStateDoubleAction> doubles,
							IEnumerable<GameStateResignAction> resigns,
							IEnumerable<GameStateTurnAction> turns)
        {
            GnuBgHintModule gnubg = new GnuBgHintModule(@"gnubg/ipoint.exe");

            gnubg.Initialize();

            foreach (GameStateMoveAction gsma in moves)
            {
                List<PlayHint> hints = gnubg.PlayHint(gsma.Original, 500);

                this.moves.Add(new KeyValuePair<GameStateAction, Vector>(gsma, ToMoveInput(gsma, hints)));
            }

            foreach (GameStateDoubleAction gsda in doubles)
            {
                DoubleResponseHint hint = gnubg.DoubleResponseHint(gsda.GameState);

                //Vector vector = new Vector(hint.TakeEq, hint.PassEq, System.Math.Abs(hint.PassEq - hint.TakeEq));
                this.doubles.Add(new KeyValuePair<GameStateAction, Vector>(gsda, ToDoubleInput(gsda.GameState, hint)));
            }

            foreach (GameStateResignAction gsra in resigns)
            {
                ResignResponseHint hint = gnubg.ResignResponseHint(gsra.GameState);

                Vector vector = new Vector();

                this.resigns.Add(new KeyValuePair<GameStateAction, Vector>(gsra, vector));
            }

            foreach (GameStateTurnAction gsta in turns)
            {
                DoubleHint hint = null;
                if (gsta.GameState.CanDouble())
                    hint = gnubg.DoubleHint(gsta.GameState);

                this.turns.Add(new KeyValuePair<GameStateAction, Vector>(gsta, ToTurnInput(gsta.GameState, hint)));
            }

            random.Next();
            random.Next();
        }
        public static double ComputeDistance(Vector v1, Vector v2)
        {
            double distance = 0.0;
            double diff = 0.0;
            for (int i = 0; i < v1.inputs.Length; i++)
            {
                diff = v1[i] - v2[i];
                distance += diff * diff;
            }

            return System.Math.Sqrt(distance);
        }
        private Vector ToTurnInput(GameState gs, DoubleHint hint)
        {
            double ratio = 0.0;
            Vector vector = null;

            if (gs.CanDouble())
            {
                if (gs.GameType == GameType.Match)
                {
                    ratio = System.Math.Min(
                        (System.Math.Max(gs.Score(0), gs.Score(1)) + gs.Cube.Value) / (double)gs.MatchTo,
                        1.0);
                }

                if (gs.GameType == GameType.Money)
                {
                    ratio = System.Math.Min(gs.Cube.Value * gs.Stake / (double)gs.Limit, 1.0);
                }

                vector = new Vector(System.Math.Abs(System.Math.Min(hint.DoubleTakeEq, hint.DoublePassEq) - hint.NoDoubleEq),
                                        ratio, 100.0);
            }
            else
            {
                vector = new Vector(0.0, ratio, 0.0);
            }

            return vector;
        }