/// <summary> /// 更具方向获取x轴和y轴的增量 /// </summary> /// <param name="dir">方向</param> /// <param name="dx">x增量</param> /// <param name="dy">y增量</param> private void _GetVariation(SnakeDirection dir, out int dx, out int dy) { switch (dir) { case SnakeDirection.Up: dx = 0; dy = -1; break; case SnakeDirection.Down: dx = 0; dy = 1; break; case SnakeDirection.Left: dx = -1; dy = 0; break; case SnakeDirection.Right: dx = 1; dy = 0; break; default: dx = 1; dy = 0; break; } }
private void StartNewGame() { bdrWelcomeMessage.Visibility = Visibility.Collapsed; bdrHighscoreList.Visibility = Visibility.Collapsed; bdrEndOfGame.Visibility = Visibility.Collapsed; foreach (SnakePart snakeBodyPart in snakeParts) { if (snakeBodyPart.UiElement != null) { GameArea.Children.Remove(snakeBodyPart.UiElement); } } snakeParts.Clear(); if (snakeFood != null) { GameArea.Children.Remove(snakeFood); } currentScore = 0; snakeLength = SnakeStartLength; snakeDirection = SnakeDirection.Right; snakeParts.Add(new SnakePart() { Position = new Point(SnakeSquareSize * 5, SnakeSquareSize * 5) }); gameTickTimer.Interval = TimeSpan.FromMilliseconds(SnakeStartSpeed); DrawSnake(); DrawSnakeFood(); UpdateGameStatus(); gameTickTimer.IsEnabled = true; }
private void StartNewGame() { foreach (snakePart snakeBodyPart in snakeBodyParts) { if (snakeBodyPart.UiElement != null) { GameArea.Children.Remove(snakeBodyPart.UiElement); } } snakeBodyParts.Clear(); if (food != null) { GameArea.Children.Remove(food); } score = 0; snakeLength = SnakeStartingLength; snakeDirection = SnakeDirection.Right; snakeBodyParts.Add(new snakePart() { Position = new Point(SnakePartsSize * 5, SnakePartsSize * 5) }); gameTimer.Interval = TimeSpan.FromMilliseconds(SnakeStartingSpeed); DrawSnake(); DrawFood(); UpdateGameStatus(); gameTimer.IsEnabled = true; }
public bool is_dir_ok(SnakeDirection dir) { Point n_point = dir2coord(dir); // Wall collision if (n_point.X < 0 || n_point.X >= GridWidth || n_point.Y < 0 || n_point.Y >= GridHeight) { return(false); } // Snake Collision for (int i = 0; i < enemies.Length; i++) { if (enemies[i].Alive) { if (enemies[i].BodyParts.Any(b => b.X == n_point.X && b.Y == n_point.Y)) { return(false); } } } if (BodyParts.Take(BodyLength - 1).Any(b => b.X == HeadPosX && b.Y == HeadPosY)) { return(false); } if (((int)dir + 2) % 4 == (int)Direction) { return(false); } return(true); }
List <Point> GetNextPossiblePoints(Point p, SnakeDirection d) { List <SnakeDirection> dirs = GetPossibleDirections(d); List <Point> points = new List <Point>(); for (int i = 0; i < dirs.Count; i++) { int xdir, ydir; DirectionToXY(dirs[i], out xdir, out ydir); points.Add(new Point(p.X + xdir, p.Y + ydir)); } return(points); }
private void Initialize() { SnakePos = new List <Tuple <int, int> >(); for (var i = 0; i < 3; i++) { SnakePos.Add(_snakePos); } _directionToMove = SnakeDirection.Right; _direction = _directionToMove; _grow = false; _moveCounter = _speed; IsSnakeNew = true; }
/// <summary> /// 贪吃蛇游戏初始化 /// </summary> public void SnakeGameRenew() { SnakeBody _body; _SnakeList.Clear();//清空所有数据 //初始化游戏运行数据 _Direction = SnakeDirection.Right; _Life = SnakeLife.Live; _Score = 0; //初始化蛇头 _body = new SnakeBody(0, 0, _SColor, true, SnakeProperty.Head); _SnakeList.Add(_body); //创建初始蛇身 int initLength = 3; if (initLength > 1) { int dx = 0, dy = 0; int x = _SnakeList[0].x, y = _SnakeList[0].y; _GetVariation(_Direction, out dy, out dy); for (int i = 1; i < initLength; i++) { x -= (dx * _BodySize); y -= (dy * _BodySize); _body = new SnakeBody(x, y, _SColor, true, SnakeProperty.Body); _SnakeList.Add(_body); } } //初始化食物 int fx = 0, fy = 0; _Food.color = _SColor; _Food.exist = true; _Food.proty = SnakeProperty.Food; _SnakeGetRandomXY(out fx, out fy); _Food.x = fx; _Food.y = fy; //重绘游戏画面 _SnakeClearWindow(); _SnakeReDrawGame(); }
List <SnakeDirection> GetPossibleDirections(SnakeDirection dir) { List <SnakeDirection> dirs = new List <SnakeDirection>(); if (Env.constRand.Next(2) == 0) { dirs.Add((SnakeDirection)(((int)dir + 1) % 4)); dirs.Add((SnakeDirection)(((int)dir + 3) % 4)); } else { dirs.Add((SnakeDirection)(((int)dir + 3) % 4)); dirs.Add((SnakeDirection)(((int)dir + 1) % 4)); } dirs.Add(dir); return(dirs); }
private void Window_KeyUp(object sender, KeyEventArgs e) { SnakeDirection originalSnakeDirection = snakeDirection; switch (e.Key) { case Key.Up: if (snakeDirection != SnakeDirection.Down) { snakeDirection = SnakeDirection.Up; } break; case Key.Down: if (snakeDirection != SnakeDirection.Up) { snakeDirection = SnakeDirection.Down; } break; case Key.Left: if (snakeDirection != SnakeDirection.Right) { snakeDirection = SnakeDirection.Left; } break; case Key.Right: if (snakeDirection != SnakeDirection.Left) { snakeDirection = SnakeDirection.Right; } break; case Key.Space: StartNewGame(); break; } if (snakeDirection != originalSnakeDirection) { MoveSnake(); } }
public void Movement() { if (--_moveCounter == 0) { IsSnakeNew = false; _moveCounter = _speed; _direction = _directionToMove; //TODO: Maybe set a snake part length 50 to make it move faster switch (Direction) { case SnakeDirection.Up: //negative y _snakePos = new Tuple <int, int>(_snakePos.Item1, _snakePos.Item2 - 1); SnakePos.Add(_snakePos); break; case SnakeDirection.Right: //positive x _snakePos = new Tuple <int, int>(_snakePos.Item1 + 1, _snakePos.Item2); SnakePos.Add(_snakePos); break; case SnakeDirection.Down: //positive y _snakePos = new Tuple <int, int>(_snakePos.Item1, _snakePos.Item2 + 1); SnakePos.Add(_snakePos); break; case SnakeDirection.Left: //negative x _snakePos = new Tuple <int, int>(_snakePos.Item1 - 1, _snakePos.Item2); SnakePos.Add(_snakePos); break; } if (_grow != true) { SnakePos.RemoveAt(0); } _grow = false; } }
private void StartNewGame() { // Удаление змейки из предыдущей игры foreach (SnakePart snakeBodyPart in snakeParts) { if (snakeBodyPart.UiElement != null) { GameArea.Children.Remove(snakeBodyPart.UiElement); } } snakeParts.Clear(); if (snakeFood != null) { GameArea.Children.Remove(snakeFood); } // Перезапуск currentScore = 0; snakeLength = SnakeStartLength; snakeDirection = SnakeDirection.Right; snakeParts.Add(new SnakePart() { Position = new Point(SnakeSquareSize * 3, SnakeSquareSize * 5) }); snakeParts.Add(new SnakePart() { Position = new Point(SnakeSquareSize * 4, SnakeSquareSize * 5) }); snakeParts.Add(new SnakePart() { Position = new Point(SnakeSquareSize * 5, SnakeSquareSize * 5), IsHead = true }); gameTickTimer.Interval = TimeSpan.FromMilliseconds(SnakeStartSpeed); DrawGameArea(); DrawSnake(); DrawSnakeFood(); UpdateGameStatus(); gameTickTimer.IsEnabled = true; }
private void GameArea_MouseLeftButtonDown(object sender, RoutedEventArgs e) { SnakeDirection originalSnakeDirection = snakeDirection; if (originalSnakeDirection == SnakeDirection.Down) { snakeDirection = SnakeDirection.Right; } else if (originalSnakeDirection == SnakeDirection.Left) { snakeDirection = SnakeDirection.Down; } else if (originalSnakeDirection == SnakeDirection.Right) { snakeDirection = SnakeDirection.Up; } else if (originalSnakeDirection == SnakeDirection.Up) { snakeDirection = SnakeDirection.Left; } MoveSnake(); }
private Point dir2coord(SnakeDirection dir) { Point pos = new Point(HeadPosX, HeadPosY); if (dir == SnakeDirection.Right) { pos.X += 1; } else if (dir == SnakeDirection.Down) { pos.Y += 1; } else if (dir == SnakeDirection.Left) { pos.X -= 1; } else if (dir == SnakeDirection.Up) { pos.Y -= 1; } return(pos); }
protected override EnvSnake.Action GetAction() { if (!Alive) { return new EnvSnake.Action() { movementDirection = SnakeDirection.Right } } ; int h = GridHeight; int w = GridWidth; int[] choice = null; switch (Direction) { case SnakeDirection.Right: choice = new int[] { 0, 1, 3 }; break; case SnakeDirection.Down: choice = new int[] { 0, 1, 2 }; break; case SnakeDirection.Left: choice = new int[] { 1, 2, 3 }; break; case SnakeDirection.Up: choice = new int[] { 0, 2, 3 }; break; } int r = Env.constRand.Next(3); SnakeDirection dir = (SnakeDirection)choice[r]; //crash bot? for (int i = 0; i < enemies.Length; i++) { for (int j = 0; j < enemies[i].BodyLength; j++) { if (Math.Pow(enemies[i].BodyParts[j].X - HeadPosX, 2) + Math.Pow(enemies[i].BodyParts[j].Y - HeadPosY, 2) == 1) { if (Direction == SnakeDirection.Down || Direction == SnakeDirection.Up) { if (HeadPosX <= w - HeadPosX) { dir = SnakeDirection.Right; } else { dir = SnakeDirection.Left; } } else { if (HeadPosY <= h - HeadPosY) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Up; } } } } } // crash wall? switch (dir) { case SnakeDirection.Right: if (HeadPosX >= w - 3) { if (HeadPosY <= h - HeadPosY) { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Left; } } else { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Left; } } } break; case SnakeDirection.Down: if (HeadPosY >= h - 3) { if (HeadPosX <= w - HeadPosX) { if (choice.Contains(0)) { dir = SnakeDirection.Right; } else { dir = SnakeDirection.Up; } } else { if (choice.Contains(2)) { dir = SnakeDirection.Left; } else { dir = SnakeDirection.Up; } } } break; case SnakeDirection.Left: if (HeadPosX <= 2) { if (HeadPosY <= h - HeadPosY) { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Right; } } else { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Right; } } } break; case SnakeDirection.Up: if (HeadPosY <= 2) { if (HeadPosX <= w - HeadPosX) { if (choice.Contains(0)) { dir = SnakeDirection.Right; } else { dir = SnakeDirection.Down; } } else { if (choice.Contains(2)) { dir = SnakeDirection.Left; } else { dir = SnakeDirection.Down; } } } break; } return(new EnvSnake.Action() { movementDirection = dir, }); }
protected override EnvSnake.Action GetAction() { SnakeDirection richtung = SnakeDirection.Right; if (!this.Alive) { return(new EnvSnake.Action() { movementDirection = SnakeDirection.Down }); } if (HeadPosX == 27 && HeadPosY == 27) { } if (this.HeadPosY + 1 == this.GridHeight) { if (this.HeadPosX + 1 == GridWidth) { richtung = SnakeDirection.Up; return(new EnvSnake.Action() { movementDirection = richtung }); } else { richtung = SnakeDirection.Right; } } if (this.HeadPosX - 1 == -1) { if (this.HeadPosY + 1 == this.GridHeight) { if (this.HeadPosX + 1 == this.GridWidth) { richtung = SnakeDirection.Up; } else { richtung = SnakeDirection.Right; } } else { richtung = SnakeDirection.Down; } } else if (this.HeadPosX + 1 == GridWidth) { if (this.HeadPosY + 1 == GridHeight) { richtung = SnakeDirection.Right; } else if (this.HeadPosY - 1 == -1) { if (this.HeadPosX - 1 == -1) { richtung = SnakeDirection.Down; } else { richtung = SnakeDirection.Left; } } else { richtung = SnakeDirection.Up; } } else { richtung = SnakeDirection.Right; } return(new EnvSnake.Action() { movementDirection = richtung }); }
protected override EnvSnake.Action GetAction() { if (!Alive) { return new EnvSnake.Action() { movementDirection = SnakeDirection.Right } } ; int h = GridHeight; int w = GridWidth; int[] choice = null; switch (Direction) { case SnakeDirection.Right: choice = new int[] { 0, 1, 3 }; break; case SnakeDirection.Down: choice = new int[] { 0, 1, 2 }; break; case SnakeDirection.Left: choice = new int[] { 1, 2, 3 }; break; case SnakeDirection.Up: choice = new int[] { 0, 2, 3 }; break; } int r = Env.constRand.Next(3); SnakeDirection dir = (SnakeDirection)choice[r]; //crash bot? for (int i = 0; i < enemies.Length; i++) { for (int j = 0; j < enemies[i].BodyLength; j++) { int diff_x = enemies[i].BodyParts[j].X - HeadPosX; int diff_y = enemies[i].BodyParts[j].Y - HeadPosY; if (Math.Sqrt(Math.Pow(Math.Abs(diff_x), 2) + Math.Pow(Math.Abs(diff_y), 2)) <= 2) { if (diff_x > 0) // want to go left { if (diff_y > 0) // want to go up { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Left; } } else // want to go down { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Left; } } } else // want to go right { if (diff_y > 0) // want to go up { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Right; } } else // want to go down { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Right; } } } } } } // crash myself? if (BodyLength > 4) { for (int i = 4; i < BodyLength; i++) { int diff_x = BodyParts[i].X - HeadPosX; int diff_y = BodyParts[i].Y - HeadPosY; if (Math.Sqrt(Math.Pow(Math.Abs(diff_x), 2) + Math.Pow(Math.Abs(diff_y), 2)) <= 2) { if (diff_x > 0) // want to go left { if (diff_y > 0) // want to go up { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Left; } } else // want to go down { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Left; } } } else // want to go right { if (diff_y > 0) // want to go up { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Right; } } else // want to go down { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Right; } } } } } } // crash wall? switch (dir) { case SnakeDirection.Right: if (HeadPosX >= w - 3) { if (HeadPosY <= h - HeadPosY) { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Left; } } else { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Left; } } } break; case SnakeDirection.Down: if (HeadPosY >= h - 3) { if (HeadPosX <= w - HeadPosX) { if (choice.Contains(0)) { dir = SnakeDirection.Right; } else { dir = SnakeDirection.Up; } } else { if (choice.Contains(2)) { dir = SnakeDirection.Left; } else { dir = SnakeDirection.Up; } } } break; case SnakeDirection.Left: if (HeadPosX <= 2) { if (HeadPosY <= h - HeadPosY) { if (choice.Contains(1)) { dir = SnakeDirection.Down; } else { dir = SnakeDirection.Right; } } else { if (choice.Contains(3)) { dir = SnakeDirection.Up; } else { dir = SnakeDirection.Right; } } } break; case SnakeDirection.Up: if (HeadPosY <= 2) { if (HeadPosX <= w - HeadPosX) { if (choice.Contains(0)) { dir = SnakeDirection.Right; } else { dir = SnakeDirection.Down; } } else { if (choice.Contains(2)) { dir = SnakeDirection.Left; } else { dir = SnakeDirection.Down; } } } break; } return(new EnvSnake.Action() { movementDirection = dir, }); }
/// <summary> /// 蛇身前进一步 /// </summary> /// <param name="dir">前进方向</param> /// <returns>蛇生命值</returns> private SnakeLife SnakeMoveStep(SnakeDirection dir) { SnakeBody tail = new SnakeBody(0, 0, _SColor, true, SnakeProperty.Body); tail.x = _SnakeList[_SnakeList.Count - 1].x;//保存蛇尾坐标 tail.y = _SnakeList[_SnakeList.Count - 1].y; SnakeBody body_t = new SnakeBody(0, 0, _SColor, true, SnakeProperty.Body); for (int i = (_SnakeList.Count - 1); i > 0; i--) {//更新蛇身坐标 body_t.x = _SnakeList[i - 1].x; body_t.y = _SnakeList[i - 1].y; _SnakeList[i] = body_t; } int dx = 0, dy = 0; _GetVariation(dir, out dx, out dy); //根据移动方向获取移动xy轴上的增量 SnakeBody body_h = new SnakeBody(0, 0, _SColor, true, SnakeProperty.Head); //更新蛇头坐标 body_h.x = _SnakeList[0].x + dx; body_h.y = _SnakeList[0].y + dy; //穿墙处理 int _maxX = _Windows.Size.Width / _BodySize; int _maxY = _Windows.Size.Height / _BodySize; if (_CrossWall == false) { if ((body_h.x >= _maxX) || (body_h.x < 0) || (body_h.y >= _maxY) || (body_h.y < 0)) { _Life = SnakeLife.Die; } } if (body_h.x >= _maxX) { body_h.x = 0; } if (body_h.x < 0) { body_h.x = _maxX - 1; } if (body_h.y >= _maxY) { body_h.y = 0; } if (body_h.y < 0) { body_h.y = _maxY - 1; } _SnakeList[0] = body_h;//更新蛇头坐标 //判断是否吃到食物或咬到自己(在未更新坐标之前预判) int foodx = 0, foody = 0; SnakeProperty p = _SnakeGetPointProperty(_SnakeList[0].x, _SnakeList[0].y); switch (p) { case SnakeProperty.Food: Console.WriteLine("SnakeProperty: " + p.ToString() + " SnakeLife: " + _Life.ToString()); //吃到食物后产生一个食物,蛇身长度增加 if (_SnakeGetRandomXY(out foodx, out foody)) //创建食物 { _Food.x = foodx; _Food.y = foody; _SnakeList.Add(tail); //增加蛇身长度 _Score++; //得分增加 _Life = SnakeLife.Live; } else { _Life = SnakeLife.Win; //return _Life; } break; case SnakeProperty.Body: case SnakeProperty.Wall: Console.WriteLine("SnakeProperty: " + p.ToString() + " SnakeLife: " + _Life.ToString()); _Life = SnakeLife.Die; //死亡 //return _Life; break; case SnakeProperty.Head: case SnakeProperty.Null: default: _Life = SnakeLife.Live; break; } _SnakeClearPoint(tail); //清除蛇尾 _SnakeReDrawGame(); //更新显示蛇身 return(_Life); }
protected override EnvSnake.Action GetAction() { SnakeDirection dir = Direction; if (!Alive) { return new EnvSnake.Action() { movementDirection = SnakeDirection.Right } } ; int x = this.HeadPosX; int y = this.HeadPosY; List <SnakeDirection> dirs = GetPossibleDirections(Direction); List <SnakeDirection> freeDirs = new List <SnakeDirection>(); float bestWall = 1; int bestIndex = 0; for (int i = 0; i < dirs.Count; i++) { int xdir, ydir; DirectionToXY(dirs[i], out xdir, out ydir); float wall = IsWall(x + xdir, y + ydir); if (wall == 0) { freeDirs.Add(dirs[i]); } if (wall < bestWall) { bestWall = wall; bestIndex = i; } } if (freeDirs.Count <= 1) { dir = dirs[bestIndex]; } else { //get direction to next food //add freedom float bestScore = 999999999; bestIndex = 0; float bestDist = 99999999; for (int i = 0; i < freeDirs.Count; i++) { //calculate distance to nearest food int xdir, ydir; DirectionToXY(freeDirs[i], out xdir, out ydir); Vector2 newPos = new Vector2(x + xdir, y + ydir); for (int j = 0; j < Food.Count; j++) { float border = 4; float borderWeight = 3f; float newDist = Math.Abs(Food[j].X - newPos.X) + Math.Abs(Food[j].Y - newPos.Y); if (Food[j].X < border) { newDist += (border - Food[j].X) * borderWeight; } if (Food[j].Y < border) { newDist += (border - Food[j].Y) * borderWeight; } if (Food[j].X > GridWidth - border - 1) { newDist += (Food[j].X - (GridWidth - border - 1)) * borderWeight; } if (Food[j].Y > GridHeight - border - 1) { newDist += (Food[j].Y - (GridHeight - border - 1)) * borderWeight; } if (newDist < bestDist) { bestDist = newDist; bestIndex = i; } } } dir = freeDirs[bestIndex]; } return(new EnvSnake.Action() { movementDirection = dir, }); }
protected override EnvSnake.Action GetAction() { if (!Alive) { return(new EnvSnake.Action() { movementDirection = SnakeDirection.Down, }); } Tuple <Point, SnakeDirection>[] dir_points = get_possible_directions(); float[] point_dists = new float[dir_points.Length]; int min_dist_idx = 0; float global_min_food_dist = float.MaxValue; bool[] head_collision = new bool[dir_points.Length]; int min_idx_no_head_collision = -1; float global_min_food_dist_no_head_collision = float.MaxValue; for (int i = 0; i < dir_points.Length; i++) { float min_food_dist = float.MaxValue; for (int j = 0; j < Food.Count; j++) { float dist = calc_dist(Food[j], dir_points[i].Item1); if (dist < min_food_dist) { min_food_dist = dist; } } point_dists[i] = min_food_dist; if (min_food_dist < global_min_food_dist) { global_min_food_dist = min_food_dist; min_dist_idx = i; } if (check_no_head_collision(dir_points[i].Item1) && min_food_dist < global_min_food_dist_no_head_collision) { min_idx_no_head_collision = i; global_min_food_dist_no_head_collision = min_food_dist; } } if (dir_points.Length == 0) { // No dir_points error return(new EnvSnake.Action() { movementDirection = Direction }); } else { SnakeDirection dir = dir_points[min_dist_idx].Item2; if (min_idx_no_head_collision >= 0) { dir = dir_points[min_idx_no_head_collision].Item2; } // No dir_points error return(new EnvSnake.Action() { movementDirection = dir, }); } }
protected override EnvSnake.Action GetAction() { SnakeDirection dir = Direction; if (!Alive) { return new EnvSnake.Action() { movementDirection = SnakeDirection.Right } } ; int x = this.HeadPosX; int y = this.HeadPosY; List <SnakeDirection> dirs = GetPossibleDirections(Direction); List <SnakeDirection> freeDirs = new List <SnakeDirection>(); float bestWall = 1; int bestIndex = 0; for (int i = 0; i < dirs.Count; i++) { int xdir, ydir; DirectionToXY(dirs[i], out xdir, out ydir); float wall = IsWall(x + xdir, y + ydir); if (wall == 0) { freeDirs.Add(dirs[i]); } if (wall < bestWall) { bestWall = wall; bestIndex = i; } } if (freeDirs.Count <= 1) { dir = dirs[bestIndex]; } else { //get direction to next food //add freedom float bestScore = 999999999; bestIndex = 0; for (int i = 0; i < freeDirs.Count; i++) { //calculate distance to nearest food int xdir, ydir; DirectionToXY(freeDirs[i], out xdir, out ydir); Vector2 newPos = new Vector2(x + xdir, y + ydir); float bestDist = 99999999; List <Point> track = new List <Point>(); track.AddRange(Food); //track.AddRange(enemies.Select(f => f.Alive ? f.BodyParts[0] : new Point(9999, 9999))); for (int j = 0; j < track.Count; j++) { float border = 4; float borderWeight = 3f; float newDist = Math.Abs(track[j].X - newPos.X) + Math.Abs(track[j].Y - newPos.Y); if (track[j].X < border) { newDist += (border - track[j].X) * borderWeight; } if (track[j].Y < border) { newDist += (border - track[j].Y) * borderWeight; } if (track[j].X > GridWidth - border - 1) { newDist += (track[j].X - (GridWidth - border - 1)) * borderWeight; } if (track[j].Y > GridHeight - border - 1) { newDist += (track[j].Y - (GridHeight - border - 1)) * borderWeight; } if (newDist < bestDist) { bestDist = newDist; } } //calculate freedom int max = 100; float count = FloodFillCount(new Point(x + xdir, y + ydir), max); count *= count; count *= 1f / (max * max); if (count >= 1) { count = 1; } else { } float score = bestDist - count * 10;//2114 if (score < bestScore) { bestScore = score; bestIndex = i; } } dir = freeDirs[bestIndex]; } return(new EnvSnake.Action() { movementDirection = dir, }); }
void DirectionToXY(SnakeDirection dir, out int xDir, out int yDir) { xDir = dir == SnakeDirection.Right ? 1 : dir == SnakeDirection.Left ? -1 : 0; yDir = dir == SnakeDirection.Down ? 1 : dir == SnakeDirection.Up ? -1 : 0; }
protected override EnvSnake.Action GetAction() { if (!Alive) { return new EnvSnake.Action() { movementDirection = SnakeDirection.Right } } ; int h = GridHeight; int w = GridWidth; int[] choice = null; switch (Direction) { case SnakeDirection.Right: choice = new int[] { 0, 1, 3 }; break; case SnakeDirection.Down: choice = new int[] { 0, 1, 2 }; break; case SnakeDirection.Left: choice = new int[] { 1, 2, 3 }; break; case SnakeDirection.Up: choice = new int[] { 0, 2, 3 }; break; } int r = Env.constRand.Next(3); SnakeDirection dir = (SnakeDirection)choice[r]; //crash bot or self? int[] risk = new int[3]; for (int i = 0; i < 3; i++) { SnakeDirection dir_temp = (SnakeDirection)choice[i]; int place_temp_x = HeadPosX; int place_temp_y = HeadPosY; switch (dir_temp) { case SnakeDirection.Right: place_temp_x += 1; break; case SnakeDirection.Down: place_temp_y += 1; break; case SnakeDirection.Left: place_temp_x -= 1; break; case SnakeDirection.Up: place_temp_y -= 1; break; } if (place_temp_x < 0 || place_temp_y < 0 || place_temp_x >= GridWidth || place_temp_y >= GridHeight) { risk[i] += 4; } for (int k = 0; k < enemies.Length; k++) { if (enemies[k].Alive) { for (int j = 0; j < enemies[k].BodyLength - 1; j++) { if ((enemies[k].BodyParts[j].X == place_temp_x) & (enemies[k].BodyParts[j].Y == place_temp_y)) { risk[i] += 2; } } if (Math.Abs(enemies[k].BodyParts[enemies[k].BodyLength - 1].X - place_temp_x) + Math.Abs(enemies[k].BodyParts[enemies[k].BodyLength - 1].Y - place_temp_y) <= 2) { if (Math.Abs(enemies[k].BodyParts[enemies[k].BodyLength - 1].X - place_temp_x) + Math.Abs(enemies[k].BodyParts[enemies[k].BodyLength - 1].Y - place_temp_y) <= 1) { risk[i] += 2; } else { risk[i] += 1; } } } } if (BodyLength > 4) { for (int j = 3; j < BodyLength - 1; j++) { { if ((BodyParts[j].X == place_temp_x) & (BodyParts[j].Y == place_temp_y)) { risk[i] += 2; } } } } } if (risk.Max() == 0) { dir = (SnakeDirection)r; } else { for (int i = 0; i < 3; i++) { if (risk[i] == risk.Min()) { dir = (SnakeDirection)choice[i]; } } } // crash wall? //switch (dir) //{ // case SnakeDirection.Right: // if (HeadPosX >= w - 3) // { // if (HeadPosY <= h - HeadPosY) // { // if (choice.Contains(1)) { dir = SnakeDirection.Down; } // else dir = SnakeDirection.Left; // } // else // { // if (choice.Contains(3)) { dir = SnakeDirection.Up; } // else dir = SnakeDirection.Left; // } // } // break; // case SnakeDirection.Down: // if (HeadPosY >= h - 3) // { // if (HeadPosX <= w - HeadPosX) // { // if (choice.Contains(0)) { dir = SnakeDirection.Right; } // else dir = SnakeDirection.Up; // } // else // { // if (choice.Contains(2)) { dir = SnakeDirection.Left; } // else dir = SnakeDirection.Up; // } // } // break; // case SnakeDirection.Left: // if (HeadPosX <= 2) // { // if (HeadPosY <= h - HeadPosY) // { // if (choice.Contains(1)) dir = SnakeDirection.Down; // else dir = SnakeDirection.Right; // } // else // { // if (choice.Contains(3)) dir = SnakeDirection.Up; // else dir = SnakeDirection.Right; // } // } // break; // case SnakeDirection.Up: // if (HeadPosY <= 2) // { // if (HeadPosX <= w - HeadPosX) // { // if (choice.Contains(0)) { dir = SnakeDirection.Right; } // else dir = SnakeDirection.Down; // } // else // { // if (choice.Contains(2)) { dir = SnakeDirection.Left; } // else dir = SnakeDirection.Down; // } // } // break; //} return(new EnvSnake.Action() { movementDirection = dir, }); }