조정 된 박테리아
늦지 않았기를 바랍니다.
내 테스트에서 다른 상대방과 항상 (그리고 항상 그들을 모두 죽여서) 승리하십시오. 전투가 그 자체에 직면하면 전략이 강력하다는 증거가 결코 끝나지 않을 것입니다.
단일 셀인 경우 이전 상태를 기억할 수 있지만 자신의 위치를 활용하여 다르게 동작 할 수 있습니다! =)
이것은 박테리아를 디바이더와 발동기로 나눌 것이며, 그렇게함으로써 방어선을 유지하면서 일선 대신에 더 많은 박테리아를 유용하게 유지할 수 있습니다.
또한 적을 더 빨리 죽일 수 있도록 공격을 조정하여 적을 더 빨리 죽입니다 (HP에 중점을 둔 다른 단일 셀을 향하게하는 것입니다).
보드의 세포 수에 의해 감지되는 게임 중반에, 그들은 플 랭킹을하여 적의 영토로 밀려 고 시도 할 것입니다. 이것이 핵심 전략입니다.
현재 다른 모든 상대에 비해 가장 높은 성장률을 보였지만 시작 속도가 느리므로 큰 경기장에서 더 잘 작동합니다.
로 실행 java CoordinatedBacteria
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
public class CoordinatedBacteria {
public static final int MAX_HP = 6;
public static final int MAX_ENERGY = 6;
public static final int ACIDITY = 0;
// given arena state and cell stats, return an action string (e.g., "ATTACK NW 2", "DIVIDE S")
public static String decide(final Arena arena, Point cell, int hp, int energy) {
// empty and corpses are free for movement and division
final Point2D enemyCenter = arena.getCenterOf("x");
final Point2D ourCenter = arena.getCenterOf("o");
final int moverPos = (enemyCenter.x <= ourCenter.x || enemyCenter.y <= ourCenter.y) ? (arena.width+arena.height+1)%2 : 1;
final int attackPos = (enemyCenter.x <= ourCenter.x || enemyCenter.y <= ourCenter.y) ? (arena.width+arena.height)%2 : 1;
int selfCount = arena.count("o");
boolean isMidWay = selfCount > (arena.width*arena.height/2-1);
if(!isMidWay){
if(enemyCenter.x < ourCenter.x){
enemyCenter.x = 0;
enemyCenter.y = 0;
ourCenter.x = arena.width;
ourCenter.y = arena.height;
} else {
enemyCenter.x = arena.width;
enemyCenter.y = arena.height;
ourCenter.x = 0;
ourCenter.y = 0;
}
}
ArrayList<Point> nearbyEmpty = arena.getAdjacentMatches(cell, ".");
Collections.sort(nearbyEmpty, new Comparator<Point>(){
@Override
public int compare(Point o1, Point o2) {
Double score1 = arena.getAdjacentMatches(o1, ".").size()
+ arena.getAdjacentMatches(o1, "c").size()
+ arena.getAdjacentMatches(o1, "x").size()
- arena.getAdjacentMatches(o1, "o").size()
+ distance(o1.x, o1.y, enemyCenter.x, enemyCenter.y)*100;
Double score2 = arena.getAdjacentMatches(o2, ".").size()
+ arena.getAdjacentMatches(o2, "c").size()
+ arena.getAdjacentMatches(o2, "x").size()
- arena.getAdjacentMatches(o2, "o").size()
+ distance(o1.x, o1.y, enemyCenter.x, enemyCenter.y)*100;
return Double.compare(score2, score1);
}
});
ArrayList<Point> nearbyEnemies = arena.getAdjacentMatches(cell, "x");
Collections.sort(nearbyEnemies, new Comparator<Point>(){
@Override
public int compare(Point o1, Point o2) {
Integer score1 = (arena.getAdjacentMatches(o1, ".").size()
+ arena.getAdjacentMatches(o1, "c").size()
- arena.getAdjacentMatches(o1, "x").size()
+ arena.getAdjacentMatches(o1, "o").size())
*10
+ (isAtBoundary(o1, arena)?1000:0)
+ (o1.x + o1.y + attackPos + 1)%2;
Integer score2 = (arena.getAdjacentMatches(o2, ".").size()
+ arena.getAdjacentMatches(o2, "c").size()
- arena.getAdjacentMatches(o2, "x").size()
+ arena.getAdjacentMatches(o2, "o").size())
*10
+ (isAtBoundary(o2, arena)?1000:0)
+ (o2.x + o2.y + attackPos + 1)%2;
return Integer.compare(score2, score1);
}
});
ArrayList<Point> nearbyCorpses = arena.getAdjacentMatches(cell, "c");
Collections.sort(nearbyCorpses, new Comparator<Point>(){
@Override
public int compare(Point o1, Point o2) {
Integer score1 = arena.getAdjacentMatches(o1, "x").size()
- arena.getAdjacentMatches(o1, "o").size();
Integer score2 = arena.getAdjacentMatches(o2, "x").size()
- arena.getAdjacentMatches(o2, "o").size();
return Integer.compare(score1, score2);
}
});
ArrayList<Point> nearbyFriends = arena.getAdjacentMatches(cell, "o");
for(Point empty: nearbyEmpty){
if(nearbyFriends.size()>=2 && energy >= 1 && arena.getAdjacentMatches(empty, "x").size()==3 && isAtBoundary(empty, arena)){
return "MOVE "+arena.getDirection(cell, empty);
}
}
for(Point empty: nearbyCorpses){
if(nearbyFriends.size()>=2 && energy >= 1 && arena.getAdjacentMatches(empty, "x").size()==3 && isAtBoundary(empty, arena)){
return "MOVE "+arena.getDirection(cell, empty);
}
}
if ((cell.x+cell.y)%2 == moverPos && energy >= 1 && energy <= 5){
if(nearbyEmpty.size()>0){
Point foremost = nearbyEmpty.get(0);
if(nearbyFriends.size() >= 4){
return "MOVE "+arena.getDirection(cell, foremost);
}
}
if(nearbyCorpses.size() > 0) {
Point corpse = nearbyCorpses.get(0);
return "EAT " + arena.getDirection(cell, corpse);
}
if(energy > 0 && nearbyEnemies.size() > 0) {
int attackStrength = Math.min(energy, 3);
Point enemy = nearbyEnemies.get(0);
return "ATTACK " + arena.getDirection(cell, enemy) + " " + attackStrength;
}
if(nearbyFriends.size() >= 4 && nearbyEmpty.size() > 0){
Point movePoint = getBestPointToDivide(arena, nearbyEmpty);
return "MOVE " + arena.getDirection(cell, movePoint);
}
}
if(energy >= 5 && nearbyEmpty.size() > 0) {
Point divisionPoint = getBestPointToDivide(arena, nearbyEmpty);
if(energy == MAX_ENERGY && nearbyFriends.size() >= 5
&& distance(enemyCenter.x, enemyCenter.y, cell.x, cell.y) > distance(enemyCenter.x, enemyCenter.y, divisionPoint.x, divisionPoint.y)){
return "MOVE " + arena.getDirection(cell, divisionPoint);
}
return "DIVIDE " + arena.getDirection(cell, divisionPoint);
}
if(nearbyCorpses.size() > 0) {
Point corpse = nearbyCorpses.get(0);
if (energy < MAX_ENERGY){
return "EAT " + arena.getDirection(cell, corpse);
} else {
return "DIVIDE " + arena.getDirection(cell, corpse);
}
}
if(energy >= 5 && nearbyCorpses.size() > 0) {
Point divisionPoint = getBestPointToDivide(arena, nearbyCorpses);
if(energy == MAX_ENERGY && nearbyFriends.size() >= 5
&& distance(enemyCenter.x, enemyCenter.y, cell.x, cell.y) < distance(enemyCenter.x, enemyCenter.y, divisionPoint.x, divisionPoint.y)){
return "MOVE " + arena.getDirection(cell, divisionPoint);
}
return "DIVIDE " + arena.getDirection(cell, divisionPoint);
}
// if at least one adjacent enemy, attack if possible
if(energy > 0 && nearbyEnemies.size() > 0) {
int attackStrength = Math.min(energy, 3);
Point enemy = nearbyEnemies.get(0);
return "ATTACK " + arena.getDirection(cell, enemy) + " " + attackStrength;
}
return "REST";
}
public static boolean isAtBoundary(Point point, Arena arena){
return point.x==0 || point.x==arena.width-1 || point.y==0 || point.y==arena.height-1;
}
public static double distance(double x1, double y1, double x2, double y2){
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
public static Point getBestPointToDivide(Arena arena, List<Point> nearbyEmpty){
Point result = null;
double minDist = 100000;
List<Point> mostEmpty = new ArrayList<Point>();
int max = -1000;
List<Point> neighbor = nearbyEmpty;
for(Point point: neighbor){
int emptyNeighborScore = arena.getAdjacentMatches(point, ".").size()
+ arena.getAdjacentMatches(point, "c").size()
+ arena.getAdjacentMatches(point, "x").size()
- arena.getAdjacentMatches(point, "o").size();
if(emptyNeighborScore > max){
mostEmpty = new ArrayList<Point>();
mostEmpty.add(point);
max = emptyNeighborScore;
} else if(emptyNeighborScore == max){
mostEmpty.add(point);
}
}
for(Point point: mostEmpty){
Point2D enemyCenter = arena.getCenterOf("x");
double dist = Math.pow(point.x-enemyCenter.x, 2) + Math.pow(point.y-enemyCenter.y, 2);
if(dist < minDist){
minDist = dist;
result = point;
}
}
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String firstLine;
firstLine = br.readLine();
if(firstLine.equals("BEGIN")) {
System.out.println(MAX_HP + " " + MAX_ENERGY + " " + ACIDITY);
} else {
String[] dimensions = firstLine.split(" ");
int width = Integer.parseInt(dimensions[0]);
int height = Integer.parseInt(dimensions[1]);
Point[][] arena = new Point[height][];
String input;
int lineno = 0;
while(!(input=br.readLine()).equals("")) {
char[] charList = input.toCharArray();
arena[lineno] = new Point[width];
for(int i=0; i<charList.length; ++i) {
arena[lineno][i] = new Point(i, lineno, charList[i]);
}
lineno++;
}
String[] stats = br.readLine().split(" ");
int x = Integer.parseInt(stats[0]);
int y = Integer.parseInt(stats[1]);
int hp = Integer.parseInt(stats[2]);
int energy = Integer.parseInt(stats[3]);
Arena arenaObj = new Arena(arena, width, height);
System.out.print(decide(arenaObj, arenaObj.get(x,y), hp, energy));
}
}
public static class Arena {
public Point[][] array;
public HashMap<String, String> c2d;
public int height;
public int width;
public Arena(Point[][] array, int width, int height) {
this.array = array;
this.width = width;
this.height = height;
this.c2d = new HashMap<String, String>();
this.c2d.put("0,0", "-");
this.c2d.put("0,-1", "N");
this.c2d.put("0,1", "S");
this.c2d.put("1,0", "E");
this.c2d.put("-1,0", "W");
this.c2d.put("-1,-1", "NW");
this.c2d.put("1,-1", "NE");
this.c2d.put("-1,1", "SW");
this.c2d.put("1,1", "SE");
}
// get the character at x,y
// or return empty string if out of bounds
public Point get(int x, int y) {
if(y < 0 || y >= this.array.length){
return null;
}
Point[] row = this.array[y];
if(x < 0 || x >= row.length) {
return null;
}
return row[x];
}
// get arraylist of Points for each adjacent space that matches the target string
public ArrayList<Point> getAdjacentMatches(Point p, String match) {
ArrayList<Point> result = new ArrayList<Point>();
for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j) {
Point found = this.get(p.x+i, p.y+j);
if((i!=0 || j!=0) && found != null && found.symbol.equals(match)) {
result.add(found);
}
}
}
return result;
}
public ArrayList<Point> getAdjacents(Point p){
ArrayList<Point> result = new ArrayList<Point>();
for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j) {
Point found = this.get(p.x+i, p.y+j);
if((i!=0 || j!=0) && found != null) {
result.add(found);
}
}
}
return result;
}
public int count(String sym){
int result = 0;
for(int y=0; y<array.length; y++){
for(int x=0; x<array[y].length; x++){
Point cur = this.get(x, y);
if(cur!=null && cur.symbol.equals(sym)){
result++;
}
}
}
return result;
}
// get the direction string from point 1 to point 2
public String getDirection(Point p1, Point p2) {
int dx = p2.x - p1.x;
int dy = p2.y - p1.y;
dx = Math.abs(dx) / (dx==0?1:dx);
dy = Math.abs(dy) / (dy==0?1:dy);
return this.c2d.get(dx + "," + dy);
}
public Point2D getCenterOf(String sym){
Point2D result = new Point2D(0,0);
int count = 0;
for(int y=0; y<array.length; y++){
for(int x=0; x<array[y].length; x++){
if(this.get(x,y).symbol.equals(sym)){
result.x += x;
result.y += y;
count++;
}
}
}
result.x /= count;
result.y /= count;
return result;
}
}
public static class Point {
int x, y;
String symbol;
public Point(int x, int y, String sym) {
this.x=x;
this.y=y;
this.symbol=sym;
}
public Point(int x, int y, char sym){
this(x, y, ""+sym);
}
}
public static class Point2D{
double x,y;
public Point2D(double x, double y){
this.x = x;
this.y = y;
}
}
}
'node c:/cell/cell_template.js'
지정해야하는 것처럼 각 인수에 대해 완전히 실행 가능한 명령 을 지정해야'java CellTemplate'
합니다. 챌린지 텍스트에서 더 명확하게 설명하겠습니다. 여전히 문제가있는 경우 Google (및 기술적 인 문제가있는 사람) 은 방금 만든 대화방 에서이 토론 을 계속할 수 있습니다 .