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; }
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()); }
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; }
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; }
/* * 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); }
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(); }