Example #1
0
        public string Print(bool territoryOnly = false)
        {
            const string tc = "ABCDEF";

            using (var writer = new StringWriter())
            {
                writer.WriteLine($"score: {string.Join(",", players.Select(x => x.score))}");
                writer.WriteLine($"territory: {string.Join(",", players.Select(x => x.territory))}");
                writer.WriteLine($"nitroLeft: {string.Join(",", players.Select(x => x.nitroLeft))}");
                writer.WriteLine($"slowLeft: {string.Join(",", players.Select(x => x.slowLeft))}");
                writer.WriteLine($"nitrosCollected: {string.Join(",", players.Select(x => x.nitrosCollected))}");
                writer.WriteLine($"slowsCollected: {string.Join(",", players.Select(x => x.slowsCollected))}");
                writer.WriteLine($"sawsCollected: {string.Join(",", players.Select(x => x.sawsCollected))}");
                writer.WriteLine($"opponentTerritoryCaptured: {string.Join(",", players.Select(x => x.opponentTerritoryCaptured))}");
                writer.WriteLine($"lineCount: {string.Join(",", players.Select(x => x.lineCount))}");
                for (var y = Env.Y_CELLS_COUNT - 1; y >= 0; y--)
                {
                    for (var x = 0; x < Env.X_CELLS_COUNT; x++)
                    {
                        var c = (ushort)(y * Env.X_CELLS_COUNT + x);

                        var player = -1;
                        for (var p = 0; p < players.Length; p++)
                        {
                            if (players[p].status != PlayerStatus.Eliminated && (players[p].pos == c || players[p].arrivePos == c))
                            {
                                player = p;
                                break;
                            }
                        }

                        var tomb = false;
                        for (var p = 0; p < players.Length; p++)
                        {
                            if (players[p].status == PlayerStatus.Eliminated && (players[p].pos == c || players[p].arrivePos == c))
                            {
                                tomb = true;
                                break;
                            }
                        }

                        Bonus bonus = null;
                        for (var b = 0; b < bonusCount; b++)
                        {
                            if (bonuses[b].pos == c)
                            {
                                bonus = bonuses[b];
                                break;
                            }
                        }

                        if (territoryOnly)
                        {
                            if (territory[c] == 0xFF)
                            {
                                writer.Write('.');
                            }
                            else
                            {
                                writer.Write(tc[territory[c]]);
                            }
                        }
                        else
                        {
                            if (bonus?.type == BonusType.N)
                            {
                                writer.Write('N');
                            }
                            else if (bonus?.type == BonusType.S)
                            {
                                writer.Write('S');
                            }
                            else if (bonus?.type == BonusType.Saw)
                            {
                                writer.Write('W');
                            }
                            else if (player != -1)
                            {
                                writer.Write(player);
                            }
                            else if (tomb)
                            {
                                writer.Write('*');
                            }
                            else if (lines[c] != 0)
                            {
                                writer.Write('x');
                            }
                            else if (territory[c] == 0xFF)
                            {
                                writer.Write('.');
                            }
                            else
                            {
                                writer.Write(tc[territory[c]]);
                            }
                        }
                    }

                    writer.WriteLine();
                }

                return(writer.ToString());
            }
        }
Example #2
0
        public void SetInput(RequestInput input, string my = "i")
        {
            if (players == null)
            {
                players = new Player[input.players.Count];

                territory = new byte[Env.CELLS_COUNT];
                lines     = new byte[Env.Y_CELLS_COUNT * Env.X_CELLS_COUNT];

                undos = new UndoPool(players.Length);
            }

            isGameOver = false;

            capture.Init(players.Length);

            time        = input.tick_num;
            playersLeft = input.players.Count;

            for (var c = 0; c < Env.CELLS_COUNT; c++)
            {
                territory[c] = 0xFF;
                lines[c]     = 0;
            }

            var keys = new[] { my }.Concat(input.players.Keys.Where(k => k != my)).ToList();

            for (var i = 0; i < players.Length; i++)
            {
                var key = i < keys.Count ? keys[i] : "unknown";

                if (players[i] == null)
                {
                    players[i] = new Player();
                }

                if (!input.players.TryGetValue(key, out var playerData))
                {
                    players[i].status = PlayerStatus.Eliminated;
                }
                else
                {
                    var accel = 0;
                    if (playerData.bonuses.Any(b => b.type == BonusType.N))
                    {
                        accel++;
                    }
                    if (playerData.bonuses.Any(b => b.type == BonusType.S))
                    {
                        accel--;
                    }

                    var speed = accel == 0 ? Env.SPEED
                        : accel == -1 ? Env.SLOW_SPEED
                        : accel == 1 ? Env.NITRO_SPEED
                        : throw new InvalidOperationException();

                    var v          = playerData.position;
                    var arriveTime = 0;
                    while (!v.InCellCenter())
                    {
                        v += GetShift(playerData.direction ?? throw new InvalidOperationException(), speed);
                        arriveTime++;
                    }

                    players[i].arrivePos = v.ToCellCoords().ToCoord();
                    if (arriveTime == 0)
                    {
                        players[i].pos = players[i].arrivePos;
                    }
                    else
                    {
                        players[i].pos = players[i].arrivePos.NextCoord((Direction)(((int)(playerData.direction ?? throw new InvalidOperationException()) + 2) % 4));
                    }

                    players[i].status = playerData.direction == null && i != 0
                        ? PlayerStatus.Broken
                        : PlayerStatus.Active;

                    players[i].dir       = playerData.direction;
                    players[i].score     = playerData.score;
                    players[i].shiftTime = accel == 0 ? Env.TICKS_PER_REQUEST
                        : accel == -1 ? Env.SLOW_TICKS_PER_REQUEST
                        : accel == 1 ? Env.NITRO_TICKS_PER_REQUEST
                        : throw new InvalidOperationException();

                    players[i].arriveTime                = arriveTime;
                    players[i].slowLeft                  = playerData.bonuses.FirstOrDefault(b => b.type == BonusType.S)?.ticks ?? 0;
                    players[i].nitroLeft                 = playerData.bonuses.FirstOrDefault(b => b.type == BonusType.N)?.ticks ?? 0;
                    players[i].lineCount                 = playerData.lines.Length;
                    players[i].territory                 = playerData.territory.Length;
                    players[i].slowsCollected            = 0;
                    players[i].nitrosCollected           = 0;
                    players[i].sawsCollected             = 0;
                    players[i].killedBy                  = 0;
                    players[i].opponentTerritoryCaptured = 0;

                    for (var k = 0; k < playerData.lines.Length; k++)
                    {
                        var lv = playerData.lines[k].ToCellCoords().ToCoord();
                        players[i].line[k] = lv;
                        lines[lv]          = (byte)(lines[lv] | (1 << i));
                    }

                    for (var k = 0; k < playerData.territory.Length; k++)
                    {
                        var lv = playerData.territory[k].ToCellCoords().ToCoord();
                        territory[lv] = (byte)i;
                    }
                }
            }

            if (bonuses == null || bonuses.Length < input.bonuses.Length)
            {
                bonuses = new Bonus[input.bonuses.Length];
            }

            bonusCount = 0;
            for (var i = 0; i < input.bonuses.Length; i++)
            {
                bonuses[bonusCount++] = new Bonus(input.bonuses[i]);
            }

            V GetShift(Direction direction, int d) =>
            direction == Direction.Up ? V.Get(0, d)
                : direction == Direction.Down ? V.Get(0, -d)
                : direction == Direction.Right ? V.Get(d, 0)
                : direction == Direction.Left ? V.Get(-d, 0)
                : throw new InvalidOperationException($"Unknown direction: {direction}");
        }