Beispiel #1
0
        public Frame Process(IGetKeyboardState keyboard)
        {
            if (keyboard.GetActionTime(EKeyboardAction.Esc) == 1)
            {
                GameForm.UserWantsToClose = true;
            }
            if (GameForm.UserWantsToClose && !GameForm.GameInSecondThreadIsRunning)
            {
                return(null);
            }

            if (keyboard.GetActionTime(EKeyboardAction.Fire) == 1)
            {
                PauseButtonPressed = !PauseButtonPressed;
            }
            if (_currentState.IsFinished && keyboard.GetActionTime(EKeyboardAction.Enter) == 1)
            {
                bool success = TryRunNextGame();
                if (!success)
                {
                    GameForm.UserWantsToClose = true;
                }
            }


            Frame frame = new Frame();

            //todo в проекте неплохо бы дописать Vector2 и Point2 с перегрузками операторов
            // а то в текущей реализации приходится все действия с векторами каждый раз руками делать
            //например, отсюда можно взять реализацию https://docs.google.com/document/d/16MoZCrlhzYNvMA7woEYWId7pnEpIki3JONzpyk4YTLg/edit



            //если аниматор не работает, значит все уже отрисовано,
            //и надо получить и подкинуть ему новое состояние
            if (_animator.IsFinished)
            {
                SimultaneousTurn nextTurn;
                if (!PauseButtonPressed && _turnReceiver.GetNextTurnAndComment(_currentState, keyboard, out nextTurn, ref frame))
                {
                    _engine.DoTurn(ref _currentState, nextTurn);
                    _currentState.turn++;

                    if (_currentState.turn == Const.NumberOfTurns)
                    {
                        _currentState.IsFinished = true;
                    }
                    //тут можно при желании добавить в состояние comment, чтобы он тоже было отрисован


                    //добавляем в аниматор обновленное состояние
                    _animator.Run(_currentState);
                }
            }


            _animator.DrawAll(ref frame, keyboard);

            return(frame);
        }
Beispiel #2
0
        /// <summary>
        /// если false, надо подождать, хода пока нет
        /// если true и turn == null, значит возникла ошибка, надо смотреть comment
        /// </summary>
        public bool GetNextTurnAndComment(State state, IGetKeyboardState keyboard, out SimultaneousTurn turn, ref Frame frame)
        {
            turn = null;


            //тут, опять же, две ситуации - либо оба игрока являются программами - тогда мы берем ход из
            //recordedTurns, либо делаем ход здесь и сейчас

            if (takeTurnsFromRecordedTurns)
            {
                //     if (recordedTurns.Count < 200)
                //        return false;
                return(recordedTurns.TryGetValue(state.turn, out turn));
            }


            int  weWantHisTurnNow = _savedFirstPlayerTurn == null ? 0 : 1;
            Turn smallTurn;
            bool received = GetTurn(state, state.players[weWantHisTurnNow], keyboard, out smallTurn, ref frame);

            if (received)
            {
                if (weWantHisTurnNow == 1)
                {
                    turn = new SimultaneousTurn {
                        FirstPlayerTurn = _savedFirstPlayerTurn, SecondPlayerTurn = smallTurn
                    };
                    _savedFirstPlayerTurn = null;
                    state.players.ForEach(x => x.moneySpent = 0);
                    return(true);
                }
                else
                {
                    _savedFirstPlayerTurn = smallTurn;
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Beispiel #3
0
        public static bool GetCellUnderMouse(IGetKeyboardState keyboard, out int line, out int position)
        {
            line = position = -1;
            double x = keyboard.MousePos.x;
            double y = keyboard.MousePos.y;

            if (Utility.doubleLess(y, Const.FieldOriginY) ||
                Utility.doubleGreater(y, Const.FieldOriginY + Const.TileHeight * Const.NumberOfLines))
            {
                return(false);
            }
            if (Utility.doubleLess(x, Const.FieldOriginX) ||
                Utility.doubleGreater(x, Const.FieldOriginX + Const.TileWidth * (Const.NumberOfColumns + 2)))
            {
                return(false);
            }
            line     = (int)Math.Truncate((y - Const.FieldOriginY) / Const.TileHeight);
            position = (int)Math.Truncate((x - Const.FieldOriginX) / Const.TileWidth);
            if (position <= 0 || position >= Const.NumberOfColumns + 1)
            {
                return(false);
            }
            return(true);
        }
Beispiel #4
0
        bool GetTurn(State state, Player player, IGetKeyboardState keyboard, out Turn retTurn, ref Frame frame)
        {
            retTurn = null;
            if (player.programAddress != null)
            {
                retTurn = GetTurnFromProgramExecuter(state, player);
                return(true);
            }

            ESprite color = player.Owner == OwnerType.Player1 ? ESprite.gridPoint1 : ESprite.gridPoint2;

            player.moneySpent = _commandsFromKeyboard.Where(x => x.type == Turn.CommandType.Buy).Sum(x => CreateUnit(x.arguments[0]).Cost);

            int  cellLine, cellPosition;
            bool mouseInField = GetCellUnderMouse(keyboard, out cellLine, out cellPosition);

            if (mouseInField)
            {
                Animator.RectangleAroundCell(ref frame, color, cellPosition, cellLine);
                if (keyboard.MouseClick)
                {
                    bool unitAtBase      = player.Units[cellLine] != null && player.Units[cellLine].AtBase();
                    bool unitJustCreated = _commandsFromKeyboard.Exists(x => x.type == Turn.CommandType.Buy && x.arguments[1] == cellLine);
                    if (unitAtBase || unitJustCreated)
                    {
                        _commandsFromKeyboard.Add(new Turn.Command(Turn.CommandType.Start, cellLine, cellPosition));
                    }
                    else
                    {
                        state.Message = "Нет юнита на базе";
                    }
                }

                for (var unitAction = EKeyboardAction.Unit1; unitAction <= EKeyboardAction.Unit5; unitAction++)
                {
                    if (keyboard.GetActionTime(unitAction) == 1)
                    {
                        int type        = (int)unitAction - (int)EKeyboardAction.Unit1 + 1;
                        var unit        = CreateUnit(type);
                        int playerMoney = player.Money - player.moneySpent;
                        if (player.Units[cellLine] != null && !player.Units[cellLine].AtBase())
                        {
                            state.Message = "Горизонталь занята";
                        }
                        else if (playerMoney >= unit.Cost)
                        {
                            //предыдущее убираем, чтобы деньги зря не расходовали
                            _commandsFromKeyboard.RemoveAll(x => x.type == Turn.CommandType.Buy && x.arguments[1] == cellLine);
                            // _commandsFromKeyboard.Add(new Turn.Command(Turn.CommandType.Remove,cellLine ));
                            _commandsFromKeyboard.Add(new Turn.Command(Turn.CommandType.Buy, type, cellLine, 1));
                            _commandsFromKeyboard.Add(new Turn.Command(Turn.CommandType.Start, cellLine, cellPosition));
                        }
                        else
                        {
                            state.Message = "Недостаточно денег";
                        }
                    }
                }
            }



            //рисуем выделенные ранее клетки и цифры , если создан юнит
            for (int i = 0; i < Const.NumberOfLines; i++)
            {
                var lastStartCommandonThisLine = _commandsFromKeyboard.LastOrDefault(x =>
                                                                                     x.type == Turn.CommandType.Start && x.arguments[0] == i);
                if (lastStartCommandonThisLine != null)
                {
                    Animator.RectangleAroundCell(ref frame, color, lastStartCommandonThisLine.arguments[1], i);
                }

                var lastBuyCommandonThisLine = _commandsFromKeyboard.LastOrDefault(x =>
                                                                                   x.type == Turn.CommandType.Buy && x.arguments[1] == i);
                if (lastBuyCommandonThisLine != null)
                {
                    Animator.TextInCell(ref frame, player.Owner == OwnerType.Player1 ? EFont.green : EFont.red,
                                        lastBuyCommandonThisLine.arguments[0].ToString(), lastStartCommandonThisLine.arguments[1], i);
                }
            }


            //dont forget to reflect everything in the end
            if (keyboard.GetActionTime(EKeyboardAction.Enter) == 1)
            {
                if (player.Owner == OwnerType.Player2)
                {
                    _commandsFromKeyboard.Where(x => x.type == Turn.CommandType.Start).ToList().ForEach(x => x.arguments[1] = Reflect(x.arguments[1]));
                    _commandsFromKeyboard.Where(x => x.type == Turn.CommandType.Buy).ToList().ForEach(x => x.arguments[2]   = Reflect(x.arguments[2]));
                }
                retTurn = new Turn {
                    commands = _commandsFromKeyboard, TurnStatus = ExternalProgramExecuteResult.Ok
                };
                _commandsFromKeyboard = new List <Turn.Command>();
                retTurn.input         = GetInput(state, player, player.Owner == OwnerType.Player1 ? state.players[1]: state.players[0]);
                return(true);
            }
            return(false);
        }
Beispiel #5
0
        public Frame DrawAll(ref Frame frame, IGetKeyboardState keyboard)
        {
            //тут надо все рисовать
            //примерный порядок: сначала фон, затем все IDrawable объекты, затем тексты

            #region remove sprites of dead units
            for (int n = 0; n < 2; n++)
            {
                for (int i = 0; i < Const.NumberOfLines; i++)
                {
                    Unit unit = state.players[n].Units[i];
                    if (unit == null)
                    {
                        continue;
                    }
                    if (unit.State == UnitState.Dead)
                    {
                        double deathTime = unit.DeathStage;
                        if (Utility.doubleGreaterOrEqual(stage - deathTime, 0.35))
                        {
                            foreach (DynamicObject sprite in unit.obj.objs)
                            {
                                state.objects.Remove(sprite);
                            }
                            unit.obj.objs.Clear();
                        }
                        if (Utility.doubleEqual(stage, 1.0) && deathTime > 0.0)
                        {
                            unit.DeathStage -= 1.0;
                        }
                    }
                }
            }
            #endregion

            frame.Add(new Sprite(ESprite.background, Const.ScreenWidth, Const.ScreenHeight, new Vector2(Const.ScreenWidth / 2, Const.ScreenHeight / 2)));
            var drawable = new List <IDrawable>();
            drawable.AddRange(state.objects);
            drawable.Add(state.effects);

            foreach (var d in drawable)
            {
                d.Draw(ref frame, stage, state.turn);
            }

            double left    = Const.FieldOriginX,
                   right   = Const.FieldOriginX + Const.TileWidth * (Const.NumberOfColumns + 2),
                   center  = (left + right) / 2;
            string message = state.Message;
            if (message != null)
            {
                frame.Add(new Text(EFont.orange, new Point2(TextX(message, center), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   message));
            }
            else
            {
                ///счет, деньги, номер хода


                string turn   = (Math.Max(0, state.turn - 1)).ToString(),
                       score0 = state.players[0].Score.ToString(),
                       score1 = state.players[1].Score.ToString(),
                       money0 = "-" + (state.players[0].Money - state.players[0].moneySpent).ToString() + "-",
                       money1 = "-" + (state.players[1].Money - state.players[1].moneySpent).ToString() + "-";
                frame.Add(new Text(EFont.orange, new Point2(TextX(turn, center), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   turn));
                frame.Add(new Text(EFont.green, new Point2(TextX(score0, left + Const.TileWidth / 2), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   score0));
                frame.Add(new Text(EFont.red, new Point2(TextX(score1, right - Const.TileWidth / 2), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   score1));
                frame.Add(new Text(EFont.green, new Point2(TextX(money0, left + Const.TileWidth * 3), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   money0));
                frame.Add(new Text(EFont.red, new Point2(TextX(money1, right - Const.TileWidth * 3), Const.FieldOriginY / 2), Const.smallLetterWidth, Const.smallLetterHeight,
                                   money1));
            }


            int  logLineCount  = 22;
            bool needRectangle = false;
            if (Game.PauseButtonPressed && state.turnCommentList.Count > 0)
            {
                //управление логом
                if (keyboard.GetActionTime(EKeyboardAction.Fire) == 1)
                {
                    _copied        = false;
                    _activeLogLine = state.turnCommentList.Count - 1;
                    _firstLogLine  = Math.Max(0, state.turnCommentList.Count - logLineCount);
                }
                if (keyboard.GetActionTime(EKeyboardAction.up) == 1)
                {
                    _copied        = false;
                    _activeLogLine = Math.Max(0, _activeLogLine - 5);
                    if (_activeLogLine < _firstLogLine)
                    {
                        _firstLogLine = _activeLogLine;
                    }
                }
                if (keyboard.GetActionTime(EKeyboardAction.down) == 1)
                {
                    _copied        = false;
                    _activeLogLine = Math.Min(state.turnCommentList.Count - 1, _activeLogLine + 1);
                    if (_activeLogLine >= _firstLogLine + logLineCount)
                    {
                        _firstLogLine++;
                    }
                }
                if (keyboard.GetActionTime(EKeyboardAction.I) == 1)
                {
                    Clipboard.SetText(state.inputList[_activeLogLine]);
                    _copied = true;
                }
                if (keyboard.GetActionTime(EKeyboardAction.O) == 1)
                {
                    if (state.players[_activeLogLine % 2].programAddress != null)
                    {
                        Clipboard.SetText(state.outputList[_activeLogLine]);
                        _copied = true;
                    }
                }

                needRectangle = true;
            }
            else
            {
                //показываем лог
                _firstLogLine = Math.Max(0, state.turnCommentList.Count - logLineCount);
            }

            int showCount = Math.Min(state.turnCommentList.Count, logLineCount);
            for (int i = 0; i < showCount; i++)
            {
                bool   onActive = needRectangle && (_firstLogLine + i == _activeLogLine);
                string text     = String.Format("{0}. {1}", (_firstLogLine + i) / 2, state.turnCommentList[_firstLogLine + i]);
                if (onActive && _copied)
                {
                    text = "Cкопировано";
                }
                var font = (_firstLogLine + i) % 2 == 0 ? EFont.green : EFont.red;
                var pos  = new Point2(right + 20, 24 + i * 12);
                if (onActive)
                {
                    RectangleAroundText(ref frame, pos, text);
                }
                frame.Add(new Text(font, pos, Const.smallLetterWidth, Const.smallLetterHeight, text));
            }

            //hp
            for (int line = 0; line < Const.NumberOfLines; line++)
            {
                if (state.players[0].Units[line] != null)
                {
                    var dict = state.players[0].Units[line].HpDuringTurn;
                    var hp   = dict.OrderBy(x => x.Key).Last(x => Utility.doubleGreaterOrEqual(stage, x.Key)).Value;
                    TextInCell(ref frame, EFont.green, Math.Max(0, hp).ToString(), 0, line);
                }
                if (state.players[1].Units[line] != null)
                {
                    var dict = state.players[1].Units[line].HpDuringTurn;
                    var hp   = dict.OrderBy(x => x.Key).Last(x => Utility.doubleGreaterOrEqual(stage, x.Key)).Value;
                    TextInCell(ref frame, EFont.red, Math.Max(0, hp).ToString(), Const.NumberOfColumns + 1, line);
                }
            }

            //int mouseLine, mousePosition;
            //if (TurnReceiver.GetCellUnderMouse(keyboard, out mouseLine, out mousePosition))
            //{
            //    if (state.players[0].Units[mouseLine] != null)
            //    {
            //        TextInCell(ref frame, EFont.green, state.players[0].Units[mouseLine].Hp.ToString(), 0, mouseLine);
            //    }
            //    if (state.players[1].Units[mouseLine] != null)
            //    {
            //        TextInCell(ref frame, EFont.red, state.players[1].Units[mouseLine].Hp.ToString(), Const.NumberOfColumns + 1, mouseLine);
            //    }
            //}



            UpdateStage();

            return(frame);
        }