Пример #1
0
        public void PlayOneMove()
        {
            ServerGameState latest = States[States.Count() - 1];
            ServerGameState state  = new ServerGameState(latest);

            States.Add(state);
            StatePointer = States.Count() - 1;

            //
            Debug = "";
            debug("GetSerialization()");
            string serialization = state.GetSerialization();

            debug("player.GetMove()");
            string movePlayer = player.GetMove(serialization);

            debug("human.GetMove()");
            string moveHuman = human.GetMove(serialization);

            state.PlayerDebug = player.Debug;
            state.Moves       = movePlayer + "\n" + moveHuman;

            //
            debug("updateGameState()");
            updateGameState(state);
            state.ServerDebug = Debug;
        }
Пример #2
0
 public HypersonicServer()
 {
     if (Directions.Count() == 0)
     {
         Directions.Add(new Point(1, 0));
         Directions.Add(new Point(-1, 0));
         Directions.Add(new Point(0, 1));
         Directions.Add(new Point(0, -1));
     }
     player = new HypersonicPlayer(0);
     human  = new HypersonicHuman(1);
     States.Add(ServerGameState.Initial());
 }
Пример #3
0
        private void update()
        {
            //
            int Round = Server.StatePointer;

            lblTurn.Text = (Round * 2).ToString() + "/400";
            //
            ServerGameState state = Server.GetCurrent();

            txtGameState.Text = state.GetBoard().Replace("\n", "\r\n");
            txtPlayer.Text    = state.PlayerDebug.Replace("\n", "\r\n");
            txtMoves.Text     = state.Moves.Replace("\n", "\r\n");
            txtServer.Text    = state.ServerDebug.Replace("\n", "\r\n");
            txtResults.Text   = state.Results.Replace("\n", "\r\n");
            //
            lblScore.Text = state.ScorePlayer + "/" + state.ScoreHuman;
        }
Пример #4
0
 public ServerGameState(ServerGameState state)
 {
     //
     for (int i = 0; i < W; i++)
     {
         for (int j = 0; j < H; j++)
         {
             Board[i, j] = state.Board[i, j];
         }
     }
     //
     foreach (Entity e in state.Entities)
     {
         Entities.Add(new Entity()
         {
             Type = e.Type, Team = e.Team, Position = e.Position, Rounds = e.Rounds, Range = e.Range
         });
     }
     //
     ScorePlayer = state.ScorePlayer; ScoreHuman = state.ScoreHuman;
 }
Пример #5
0
        /*
         * http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html
         * OPEN = priority queue containing START
         * CLOSED = empty set
         * while lowest rank in OPEN is not the GOAL:
         *  current = remove lowest rank item from OPEN
         *  add current to CLOSED
         *  for neighbors of current:
         *  cost = g(current) + movementcost(current, neighbor)
         *  if neighbor in OPEN and cost less than g(neighbor):
         *      remove neighbor from OPEN, because new path is better
         *  if neighbor in CLOSED and cost less than g(neighbor): ⁽²⁾
         *      remove neighbor from CLOSED
         *  if neighbor not in OPEN and neighbor not in CLOSED:
         *      set g(neighbor) to cost
         *      add neighbor to OPEN
         *      set priority queue rank to g(neighbor) + h(neighbor)
         *      set neighbor's parent to current
         */
        public static List <Point> GetPath(ServerGameState state, Point startPoint, Point endPoint)
        {
            Dictionary <Point, Point> Froms     = new Dictionary <Point, Point>();
            Dictionary <Point, int>   Steps     = new Dictionary <Point, int>();
            Dictionary <Point, int>   Distances = new Dictionary <Point, int>();
            //
            HashSet <Point> OPEN = new HashSet <Point>()
            {
                startPoint
            };
            HashSet <Point> CLOSED = new HashSet <Point>();

            //
            int Step = 0;

            Froms[startPoint]     = startPoint;
            Steps[startPoint]     = Step;
            Distances[startPoint] = 0;
            //while lowest rank in OPEN is not the GOAL
            while ((OPEN.Count() > 0) && (OPEN.OrderBy(x => Distances[x]).First() != endPoint))
            {
                //current = remove lowest rank item from OPEN
                //add current to CLOSED
                Point current = OPEN.OrderBy(x => Distances[x]).First();
                OPEN.Remove(current);
                CLOSED.Add(current);
                //for neighbors of current
                List <Point> neighbors = new List <Point>();
                neighbors.Add(new Point(current.X + 1, current.Y));
                neighbors.Add(new Point(current.X - 1, current.Y));
                neighbors.Add(new Point(current.X, current.Y + 1));
                neighbors.Add(new Point(current.X, current.Y - 1));
                foreach (Point neighbor in neighbors)
                {
                    //Is valid neighbor?
                    if (neighbor.X >= W || neighbor.X < 0 || neighbor.Y >= H || neighbor.Y < 0)
                    {
                        continue;
                    }
                    if (state.Board[neighbor.X, neighbor.Y] != '.')
                    {
                        continue;
                    }
                    if (state.Entities.Exists(e => e.Position.Equals(neighbor) && e.Type == ServerGameState.EntityType.Bomb))
                    {
                        continue;
                    }
                    //cost = g(current) + movementcost(current, neighbor)
                    int cost = Distances[current] + 1;
                    //if neighbor in OPEN and cost less than g(neighbor)
                    if (OPEN.Contains(neighbor) && (cost < Distances[neighbor]))
                    {
                        //remove neighbor from OPEN, because new path is better
                        OPEN.Remove(neighbor);
                    }
                    //if neighbor in CLOSED and cost less than g(neighbor)
                    if (CLOSED.Contains(neighbor) && (cost < Distances[neighbor]))
                    {
                        //remove neighbor from CLOSED
                        CLOSED.Remove(neighbor);
                    }
                    //if neighbor not in OPEN and neighbor not in CLOSED:
                    if (!OPEN.Contains(neighbor) && !CLOSED.Contains(neighbor))
                    {
                        //set g(neighbor) to cost
                        Distances[neighbor] = cost;
                        //add neighbor to OPEN
                        OPEN.Add(neighbor);
                        //set neighbor's parent to current
                        Froms[neighbor] = current;
                        Steps[neighbor] = Steps[current] + 1;
                    }
                }
            }

            //
            List <Point> Result = new List <Point>();

            //Impossible
            if (!Froms.ContainsKey(endPoint))
            {
                return(Result);
            }
            //
            Point currNode = endPoint;

            while (currNode != startPoint)
            {
                Result.Add(currNode);
                currNode = Froms[currNode];
            }
            //
            return(Result);
        }
Пример #6
0
        private void updateGameState(ServerGameState state)
        {
            //
            const int Exploded = 99;

            //Countdown
            foreach (ServerGameState.Entity bomb in state.Entities.Where(e => e.Type == ServerGameState.EntityType.Bomb))
            {
                bomb.Rounds--;
            }
            //Explode the bombs
            List <Point> boxes = new List <Point>();
            HashSet <Tuple <Point, int> > boxesScores = new HashSet <Tuple <Point, int> >();
            List <int> playersHit = new List <int>();

            while (state.Entities.Exists(e => e.Type == ServerGameState.EntityType.Bomb && e.Rounds == 0))
            {
                ServerGameState.Entity bomb = state.Entities.First(e => e.Type == ServerGameState.EntityType.Bomb && e.Rounds == 0);
                bomb.Rounds = Exploded;
                //
                foreach (Point p in Directions)
                {
                    //Start from 0 to include blast map and trigger bombs at the same location
                    for (int i = 0; i < bomb.Range; i++)
                    {
                        //
                        Point candidate = new Point(bomb.Position.X + p.X * i, bomb.Position.Y + p.Y * i);
                        if (candidate.X < 0 || candidate.X >= W || candidate.Y < 0 || candidate.Y >= H)
                        {
                            break;
                        }
                        state.Blasts.Add(candidate);
                        //Mark players
                        List <int> players = state.Entities
                                             .Where(e => e.Type == ServerGameState.EntityType.Player && e.Position == candidate)
                                             .Select(e => e.Team).ToList();
                        foreach (int player in players)
                        {
                            if (!playersHit.Contains(player))
                            {
                                state.Results += "Player " + player + " hit by a bomb\n";
                                playersHit.Add(player);
                            }
                        }
                        //Mark boxes and stop the blast
                        if ("012".Contains(state.Board[candidate.X, candidate.Y]))
                        {
                            Tuple <Point, int> score0 = new Tuple <Point, int>(candidate, 0);
                            Tuple <Point, int> score1 = new Tuple <Point, int>(candidate, 1);
                            if (!boxesScores.Contains(score0) && bomb.Team == 0)
                            {
                                boxesScores.Add(score0);
                                state.ScorePlayer++;
                            }
                            if (!boxesScores.Contains(score1) && bomb.Team == 1)
                            {
                                boxesScores.Add(score1);
                                state.ScoreHuman++;
                            }
                            //
                            boxes.Add(candidate);
                            break;
                        }
                        //Trigger nearby bombs
                        if (state.Entities.Exists(e => e.Type == ServerGameState.EntityType.Bomb && e.Position == candidate && e.Rounds != Exploded))
                        {
                            state.Entities.First(e => e.Type == ServerGameState.EntityType.Bomb && e.Position == candidate && e.Rounds != Exploded).Rounds = 0;
                            if (i > 0)
                            {
                                break;
                            }
                        }
                        //Stop at items
                        if (state.Entities.Exists(e => e.Type == ServerGameState.EntityType.Item && e.Position == candidate))
                        {
                            ServerGameState.Entity item = state.Entities.First(e => e.Type == ServerGameState.EntityType.Item && e.Position == candidate);
                            state.Entities.Remove(item);
                            break;
                        }
                        //Stop at walls
                        if (state.Board[candidate.X, candidate.Y] == 'X')
                        {
                            break;
                        }
                    }
                }
            }

            //Move the players
            Dictionary <int, Point> bombs = new Dictionary <int, Point>();

            //Cannot move to a box or bomb cell
            string[] moves = state.Moves.Split('\n');
            int      team  = 0;

            foreach (string move in moves)
            {
                ServerGameState.Entity player = state.Entities.Single(e => e.Team == team && e.Type == ServerGameState.EntityType.Player);
                string[] tokens = move.Split(' ');
                //
                if (tokens[0] == "BOMB")
                {
                    bombs[team]    = player.Position;
                    state.Results += "Player " + team + " wants to plant a bomb\n";
                }
                //
                Point target = new Point(int.Parse(tokens[1]), int.Parse(tokens[2]));
                if (target == player.Position)
                {
                    state.Results += "Player " + team + " standing still\n";
                    team++;
                    continue;
                }
                //
                List <Tuple <Point, int> > distances = new List <Tuple <Point, int> >();
                for (int i = 0; i < W; i++)
                {
                    for (int j = 0; j < H; j++)
                    {
                        if (state.Board[i, j] == '.')
                        {
                            Point candidate = new Point(i, j);
                            if (!state.Entities.Exists(e => e.Type == ServerGameState.EntityType.Bomb && e.Position == candidate))
                            {
                                distances.Add(new Tuple <Point, int>(candidate, Manhattan(target, candidate)));
                            }
                        }
                    }
                }
                distances = distances.OrderBy(t => t.Item2).ToList();
                //
                bool found = false;
                foreach (Tuple <Point, int> candidate in distances)
                {
                    //
                    List <Point> path = new List <Point>();
                    path.Add(player.Position);
                    if (player.Position != candidate.Item1)
                    {
                        path = GetPath(state, player.Position, candidate.Item1);
                        if (path.Count() == 0)
                        {
                            continue;
                        }
                    }
                    //
                    Point final = path[path.Count() - 1];
                    if (Manhattan(player.Position, final) > 1)
                    {
                        throw new Exception("Manhattan distance != 1");
                    }
                    state.Results  += "Player " + team + " moving to (" + final.X + ", " + final.Y + ")\n";
                    player.Position = final;
                    found           = true;
                    break;
                }
                //
                if (!found)
                {
                    state.Results += "Player " + team + " standing still\n";
                }
                team++;
            }

            //Account for powerups and pickup items
            team = 0;
            foreach (string move in moves)
            {
                ServerGameState.Entity player = state.Entities.First(e => e.Team == team && e.Type == ServerGameState.EntityType.Player);
                if (state.Entities.Exists(e => e.Type == ServerGameState.EntityType.Item && e.Position == player.Position))
                {
                    ServerGameState.Entity item = state.Entities.Single(e => e.Type == ServerGameState.EntityType.Item && e.Position == player.Position);
                    if (item.Rounds == 1)
                    {
                        player.Range  += 1;
                        state.Results += "Player " + team + " got RANGE, now at " + player.Range + "\n";
                    }
                    else if (item.Rounds == 2)
                    {
                        player.Rounds += 1;
                        state.Results += "Player " + team + " got BOMB, now at " + player.Rounds + "\n";
                    }
                }
                team++;
            }
            List <Point> playerPositions = state.Entities.Where(e => e.Type == ServerGameState.EntityType.Player).Select(e => e.Position).ToList();

            state.Entities = state.Entities.Where(e => !(e.Type == ServerGameState.EntityType.Item && playerPositions.Contains(e.Position))).ToList();

            //Boxes and items
            foreach (Point box in boxes.Distinct())
            {
                //Drop items
                if (state.Board[box.X, box.Y] == '1' || state.Board[box.X, box.Y] == '2')
                {
                    state.Entities.Add(new ServerGameState.Entity()
                    {
                        Type     = ServerGameState.EntityType.Item,
                        Team     = 0,
                        Position = box,
                        Rounds   = int.Parse("" + state.Board[box.X, box.Y]),
                        Range    = 0
                    });
                }
                //Remove box
                state.Board[box.X, box.Y] = '.';
            }

            //Place bombs
            foreach (int teamNo in bombs.Keys)
            {
                int bombCount = state.Entities.Count(e => e.Team == teamNo && e.Type == ServerGameState.EntityType.Bomb);
                int allowed   = state.Entities.Single(e => e.Team == teamNo && e.Type == ServerGameState.EntityType.Player).Rounds;
                if (bombCount >= allowed)
                {
                    state.Results += "Player " + teamNo + " limit reached " + allowed;
                }
                else if (state.Entities.Exists(e => e.Team == teamNo && e.Type == ServerGameState.EntityType.Bomb && e.Position == bombs[teamNo]))
                {
                    state.Results += "Player " + teamNo + " already planted";
                }
                else
                {
                    state.Entities.Add(new ServerGameState.Entity()
                    {
                        Team     = teamNo,
                        Position = bombs[teamNo],
                        Type     = ServerGameState.EntityType.Bomb,
                        Range    = state.Entities.Single(e => e.Team == teamNo && e.Type == ServerGameState.EntityType.Player).Range,
                        Rounds   = 8
                    });
                    state.Results += "Player " + teamNo + " planted (" + bombs[teamNo].X + ", " + bombs[teamNo].Y + ") " +
                                     "ranged " + state.Entities.Single(e => e.Team == teamNo && e.Type == ServerGameState.EntityType.Player).Range + "\n";
                }
            }

            //Remove bombs
            state.Entities = state.Entities.Where(e => e.Rounds != Exploded).ToList();
        }