뱀의 음식 부족


17

뱀의 음식 부족

35 년 만에 처음으로 뱀뱀에 식량이 부족합니다. 주민 뱀은이 음식 부족에서 살아 남기 위해 서로 싸워야합니다. 먹이 사슬의 꼭대기에는 오직 하나의 뱀만이 설 수 있습니다!


리더 보드

아직 아니야!

2 월 24 일의 마지막 업데이트

마지막 경기의 시각화에 연결


기술

마지막 남은 사과 / 체리 / 무엇을 위해 싸우려면 주어진 입력을 받아들이고 다음 동작을 반환하는 프로그램 형태로 뱀을 제공해야합니다.

유일한 비결은 당신이 구덩이에 혼자가 아니라는 것입니다. 또 다른 뱀도 희귀 한 음식을 얻으려고 노력할 것입니다! 그러나 뱀뱀 내부는 어둡기 때문에 자신과 사과 만 볼 수 있습니다. 상대에게 부딪 치면 자신을 물거나 벽을 때리는 것처럼 사망에이를 수 있습니다. 또한, 요즘 사과는 드물기 때문에 상대방이 7의 길이에 도달했을 때 굶어 죽습니다.

뱀피 트는 너비와 높이가 15 인 2 차원 맵이며, 가장 바깥 쪽 타일은 통과 할 수없는 벽을 만듭니다.

  0 1 2 . . . c d e
0 # # # # # # # # #
1 #               #
2 #           x   #
. #               #
. #               #
. #               #
c #               #
d #               #
e # # # # # # # # #

좌표는 0으로 색인화되므로의 위치 x는입니다 12,2.

봇은 두 가지 인수로 호출됩니다.

  • 음식의 위치
  • 신체 세그먼트의 위치 /

그런 다음 stdout에 다음 중 하나를 작성해야합니다.

  • L 다음 움직임으로 쿼터 좌회전
  • R 4 분기 우회전
  • 같은 방향으로 움직일 다른 것

예:

Projects/Snakepit> python bot.py 12,2 4,8/4,9/3,9/2,9
'R'
Projects/Snakepit>

규칙

당신의 봇은 :

  • 무엇이든 유효한 움직임이기 때문에 무엇이든 출력
  • ./snakes/ThisIsYourSnake 아래에있는 자체 디렉토리의 파일 읽기 / 쓰기
  • 우분투 14.04 및 Windows 7에서 실행하십시오 (실제로해야합니다)

당신의 봇은 :

  • 자체 디렉토리 외부의 파일 읽기 / 쓰기
  • 인터넷과 같은 외부 자원 사용
  • 실행 당 10 초 이상의 런타임

당신은 당신의 대답에 제공해야합니다 :

  • 봇의 소스 코드
  • 봇 / 뱀 이름
  • (자신의 이름)
  • 봇을 실행하는 명령

내 인생을 더 편하게 만들고 싶다면와 같은 줄을 제공하십시오 CoolSnake MyOwnName python bot.py.


채점

당신의 뱀은 다른 뱀과의 경기에서 이길 점수를 얻습니다. 다음과 같은 상황에서 게임이 승리합니다.

  • 상대는 자신, 당신 또는 벽을 때린다
  • 당신은 길이 7에 도달

또한 두 뱀은 200주기 후에 굶어 죽습니다.

각 뱀은 다른 뱀과의 생존을 위해 10 경기를 싸울 것입니다.


봇 예

아이디어를 드리기 위해이 두 가지 (참여하는) 예제 뱀을 제공하겠습니다.

비열한 뱀

#!/usr/bin/env python

import sys, random

def main(food, me) :
    food = [int(i) for i in food.split(",")]
    me = [[int(i) for i in seg.split(",")] for seg in me.split("/")]
    head = me[0]
    v = [head[0] - me[1][0], head[1] - me[1][1]]

    if food[0] < head[0] :
        vn = [-1, 0]
    elif food[0] > head[0] :
        vn = [1, 0]
    elif food[0] == head[0] :
        if food[1] < head[1] :
            vn = [0, -1]
        elif food[1] > head[1] :
            vn = [0, 1]

    if v == vn :
        return "..."
    elif [-v[1], v[0]] == vn :
        return "R"
    elif [v[1], -v[0]] == vn :
        return "L"
    else :
        return random.choice(("R", "L"))

if __name__ == "__main__" :
    print main(*sys.argv[1:3])

SneakySnake Cipher python bot.py

악순환

#!/usr/bin/env python

import sys, random

def main(food, me) :
    food = [int(i) for i in food.split(",")]
    me = [[int(i) for i in seg.split(",")] for seg in me.split("/")]
    head = me[0]
    v = [head[0] - me[1][0], head[1] - me[1][1]]
    vn = [food[0] - head[0], food[1] - head[1]]
    if 0 not in vn :
        vn[v.index(0)-1] = 0
    vn[vn.index(0)-1] = vn[vn.index(0)-1] / abs(vn[vn.index(0)-1])

    if v == vn :
        return "..."
    elif [v[0] + vn[0], v[1] + vn[1]] == [0, 0] :
        return random.choice(("R", "L"))
    else :
        return "R" if [-v[1], v[0]] == vn else "L"

if __name__ == "__main__" :
    print main(*sys.argv[1:3])

ViciousViper Cipher python bot.py

그리고 그들의 성냥 :

경기 예 1 경기 예 2

경기 예 3

제어 프로그램

github 에서 모든 봇 및 과거 경기 기록과 함께 제어 프로그램을 찾을 수 있습니다 .

요구 사항 :

  • Python 2 + 라이브러리 numpypillow( python -c "import numpy, PIL"모듈이 누락 된 오류가 발생하면을 통해 존재하는지 확인할 수 있습니다 )
  • 컨트롤러가 작동하려면 전체 폴더 구조를 복사해야합니다
  • 봇을 ./snakes/list.txt파일의 스타일로 파일에 등록하십시오CoolSnake MyOwnName Command To Run My Bot
  • 아래에 이름이있는 디렉토리 안에 봇을 배치하십시오 ./snakes
  • 귀하 또는 귀하의 봇 이름은 공백을 포함 할 수 없습니다!

용법:

python run.py [-h] [-n int] [-s int] [-l int] [-c int] [-g]

python run.pylist.txt에 등록 된 모든 봇과 표준 속성으로 토너먼트를 진행합니다. 고급 옵션은 다음과 같습니다.

  • -h 도움말 메시지를 표시합니다
  • -n int 상대방의 각 조합에 대한 전투 라운드
  • -s int 격자의 크기를 결정합니다 (너비와 높이)
  • -l int 승리에 필요한 길이를 설정
  • -c int 사이클 제한을 설정합니다
  • -g또는 --no-gifs일치하는 gif를 만들지 않습니다

12
봇이 다른 봇의 위치를 ​​알 수있는 방법이 거의 없다면 얼마나 흥미로운 상호 작용 전략을 얻게 될지 잘 모르겠습니다.
Martin Ender 2019

6
우리는 길이가 <7로 제한되어 있기 때문에 상대의 위치를 ​​아는 것조차 피해야합니다. 당신은 실제로 가장 간단한 차단 외에는 아무것도 할 수있을만큼 길지 않습니다. 나는 대부분의 성냥이 각 음식에 가장 가까운 사람에게 나올 것이라고 생각합니다.
Geobits

7
나는 이것을 정말로 잘하는 방법에 대한 놀라운 계획을 가지고있었습니다. 그런 다음 규칙을 더 읽으십시오. 당신이 다른 뱀을 볼 수 없다면, 당신의 선택은 실제로 "직접 경로를 밟다"또는 "약간의 길을 간다"입니다. 다른 뱀을 피하는 것이 멍청한 행운이라면 그다지 흥미롭지 않습니다.
captncraig

8
나는 당신이 이것을 통해 생각했다고 생각하지 않습니다. 당신의 적이 사과를 먹을 때, 당신은 그가 어디에 있는지 정확히 알고 있습니다. 그런 다음 현재 사과로가는 경로를 예측할 수 있습니다. 충돌 가능성없이 먼저 도달 할 수 있다는 것을 알 수 있거나 꼬리를 그의 가능한 경로를 가로 질러 드래그하여 함정을 놓을 수 있습니다. 사과를 얻는 데 걸리는 시간이나 이전 게임에서 꼬리와 충돌했을 때의 전략을 예측할 수도 있습니다. 그리고 물론, 그는 당신이 자신이 알고 있다는 것을 알고 있다는 것을 알고 있습니다. 뛰어난 퍼즐 암호 +1.
논리 기사

4
나는 원래 게임과 상대를 보는 것, 길이 제한을 늘리는 것과 같은 것들에 더 중점을 둔 분리 된 토너먼트를 만들려고 생각하고 있습니다. 관심있는 사람이 있습니까?
Cipher

답변:


6

젠-C ++여기에 이미지 설명을 입력하십시오

코 데몬 은 먹기 위해서가 아니라 싸우기 위해 여기 있습니다. 그는 죽은 적이 사과를 훔치지 않을 것임을 알고 있습니다.


Name| Author |Launch with

Zen GholGoth21 Zen.exe


전략

모든 사람 (CircleOfLife 제외)은 항상 사과가 아닌 젠에게 달려갑니다. 적이 그보다 먼저 음식에 도달 할 수 있다면, 그는 단순히 중앙에서 기다립니다 (무엇을 원하십니까? CircleOfLife?). 그렇지 않으면, Zen은 사과에 가서 무언가가 일어나기를 기다리는 동안 돌아갑니다. 실제로, 그는 사과를 미끼로 사용합니다.

그는 매우 행운으로 만 이길 수 있기 때문에 CircleOfLife의 호기심 많은 전략에 대해서는 아무것도 코딩하지 않았습니다.

코드

이것은 C ++ 프로젝트의 완전한 코드입니다. 11 개의 소스 파일과 Makefile을 잘라 내고make

$ cat src/* Makefile
/* 
 * @file    Enemy.cpp
 * @author  GholGoth21
 * @date    Créé le 1 mars 2015 à 14:10
 */

#include "Enemy.h"

#include <fstream>

Enemy::Enemy()
{
}

Enemy::~Enemy()
{
}

std::ostream &operator<<(std::ostream &os, const Enemy& e)
{
    return os<<e.m_pos<<" "<<e.m_date;
}

std::istream &operator>>(std::istream &is, Enemy& e)
{
    return is>>e.m_pos>>e.m_date;
}

int Enemy::distTo(int2 const &target, int date) const
{
    return m_pos.distTo(target)-(date-m_date);
}

bool Enemy::recentActivity(int2 const &pos, int date, int maxDelay) const
{
    return pos.distTo(m_pos)<=date-m_date && date-m_date<=maxDelay;
}
/* 
 * @file    Enemy.h
 * @author  GholGoth21
 * @date    Créé le 1 mars 2015 à 14:10
 */

#ifndef ENEMY_H
#define ENEMY_H

#include "int2.h"

class Enemy
{
public:
    Enemy();
    virtual ~Enemy();

public:
    void setPos(int2 const &pos, int date) { m_pos=pos; m_date=date; }
    int distTo(int2 const &target, int date) const;
    int2 const &pos() const { return m_pos; }
    bool recentActivity(int2 const &pos, int date, int maxDelay) const;
    friend std::ostream &operator<<(std::ostream &os, const Enemy& e);
    friend std::istream &operator>>(std::istream &is, Enemy& e);

private:
    int2 m_pos;
    int m_date;
};

#endif  /* ENEMY_H */
/* 
 * @file    Snake.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:47
 */

#include "Snake.h"
#include "enums.h"
#include "StrManip.h"
#include "Enemy.h"

#include <vector>
#include <cmath>

Snake::Snake(std::string const &body)
{
    std::vector<std::string> posList;
    split(body, '/', posList);
    for(auto &pos : posList)
        m_body.push_back(int2(pos));
}

Snake::~Snake()
{
}

Command Snake::move(int2 food, int date, Enemy const &enemy)
{
    Command bestCommand[Command::count];

    int myDist=curPos().distTo(food);
    int enemyDist=enemy.distTo(food,date);

    if(myDist>=enemyDist && enemyDist>2)
    {
        orderCommand(int2(MAPSIZE/2,MAPSIZE/2), bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]) && !enemy.recentActivity(nextPos(bestCommand[i]),date,5))
                return bestCommand[i];
    }
    if((myDist==1 && enemyDist>((len()-1)/2)*2+3) || enemyDist<-5)
    {
        orderCommand(food, bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]))
                return bestCommand[i];
    }
    int2 embushPoint;
    int minDist=-1;
    foreach_enum(Direction, d)
    {
        int2 point(food+d.vector());
        int dist=point.quadDistTo(enemy.pos());
        if(dist<minDist || minDist<0)
        {
            minDist=dist;
            embushPoint=point;
        }
    }
    if(curPos().distTo(embushPoint)<enemy.distTo(embushPoint,date)-((len()-1)/2)*2)
    {
        int minimalAction=-1;
        int qMinDist = curPos().quadDistTo(embushPoint);
        Command minimalCommand;
        foreach_enum(Command, c)
        {
            int2 np=nextPos(c);
            int qDist = np.quadDistTo(embushPoint);
            if((qDist<minimalAction || minimalAction<0) && qDist>qMinDist && validCommand(c))
            {
                minimalAction=qDist;
                minimalCommand=c;
            }
        }
        return minimalCommand;
    }
    else
    {
        orderCommand(embushPoint, food, bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]) && nextPos(bestCommand[i])!=food)
                return bestCommand[i];
    }



    return Command::forward;
}

bool Snake::validCommand(Command c) const
{
    if(!c.isValid())
        return false;
    int2 np = nextPos(c);
    if(!(0<np.x && np.x<MAPSIZE-1 && 0<np.y && np.y<MAPSIZE-1))
        return false;
    for(unsigned int i=2; i<m_body.size()-1; i++)
        if(np==m_body.at(i))
            return false;
    return true;
}

bool Snake::isStarting() const
{
    if(m_body.size()==3)
    {
        if(m_body.at(0)==int2(3,(MAPSIZE)/2) && m_body.at(1)==int2(2,(MAPSIZE)/2) && m_body.at(2)==int2(1,(MAPSIZE)/2))
            return true;
        else if(m_body.at(0)==int2(MAPSIZE-4,(MAPSIZE)/2) && m_body.at(1)==int2(MAPSIZE-3,(MAPSIZE)/2) && m_body.at(2)==int2(MAPSIZE-2,(MAPSIZE)/2))
            return true;
    }
    return false;
}

void Snake::orderCommand(int2 target, Command *tab)
{
    int weight[Command::count];
    foreach_enum(Command, c)
    {
        int2 np = nextPos(c);
        weight[c]=np.quadDistTo(target);
        tab[c]=c;
    }
    for(int i=0; i<Command::count-1; i++)
    {
        while(i>=0 && weight[tab[i]]>weight[tab[i+1]])
        {
            varSwitch(tab[i], tab[i+1]);
            i--;
        }
    }
}

void Snake::orderCommand(int2 target1, int2 target2, Command *tab)
{
    int weight[Command::count];
    foreach_enum(Command, c)
    {
        int2 np = nextPos(c);
        weight[c]=np.quadDistTo(target1)+np.quadDistTo(target2);
        tab[c]=c;
    }
    for(int i=0; i<Command::count-1; i++)
    {
        while(i>=0 && weight[tab[i]]>weight[tab[i+1]])
        {
            varSwitch(tab[i], tab[i+1]);
            i--;
        }
    }
}
/* 
 * @file    Snake.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:47
 */

#ifndef SNAKE_H
#define SNAKE_H

#include "int2.h"

#include <vector>

#define MAPSIZE 15

class Enemy;

class Snake
{
public:
    Snake(std::string const &body);
    virtual ~Snake();

public:
    Command move(int2 food, int date, Enemy const &enemy);
    Direction curDir() const { return (m_body.at(0)-m_body.at(1)).direction(); }
    int2 curPos() const { return m_body.at(0); }
    int2 nextPos(Command c) const { return curPos()+curDir().applyCommand(c).vector(); }
    bool validCommand(Command c) const;
    bool isStarting() const;
    void orderCommand(int2 target, Command *tab);
    void orderCommand(int2 target1, int2 target2, Command *tab);
    int len() const { return m_body.size(); }

private:
    std::vector<int2> m_body;
};

#endif  /* SNAKE_H */
/* 
 * @file    StrManip.cpp
 * @author  GholGoth21
 * @date    Créé le 7 février 2015 à 17:26
 */

#include "StrManip.h"

#include <sstream>

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim))
        elems.push_back(item);
    return elems;
}

int atoi(std::string const &text)
{
    std::stringstream ss(text);
    int val;
    ss >> val;
    return val;
}
/* 
 * @file    StrManip.h
 * @author  GholGoth21
 * @date    Créé le 7 février 2015 à 17:26
 */

#ifndef STRMANIP_H
#define STRMANIP_H

#include <string>
#include <vector>

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
int atoi(std::string const &text);

#endif  /* STRMANIP_H */
/* 
 * @file    enums.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:55
 */

#include "enums.h"
#include "int2.h"

Command Direction::turnTo(Direction newDir) const
{
    if(!isValid() || !newDir.isValid())
        return Command::count; //Invalid
    else if((m_value==Direction::up && newDir==Direction::left) || (m_value==Direction::left && newDir==Direction::down) ||
            (m_value==Direction::down && newDir==Direction::right) || (m_value==Direction::right && newDir==Direction::up))
        return Command::left;
    else if((m_value==Direction::up && newDir==Direction::right) || (m_value==Direction::right && newDir==Direction::down) ||
            (m_value==Direction::down && newDir==Direction::left) || (m_value==Direction::left && newDir==Direction::up))
        return Command::right;
    else if(m_value==newDir)
        return Command::forward;
    else
        return Command::count; // Invalid
}

Direction Direction::applyCommand(Command c) const
{
    if(c==Command::forward)
        return m_value;
    else if(c==Command::left)
    {
        switch(m_value)
        {
            case Direction::left:
                return Direction::down;
            case Direction::up:
                return Direction::left;
            case Direction::right:
                return Direction::up;
            case Direction::down:
                return Direction::right;
            default:
                break;
        }
    }
    else if(c==Command::right)
    {
        switch(m_value)
        {
            case Direction::left:
                return Direction::up;
            case Direction::up:
                return Direction::right;
            case Direction::right:
                return Direction::down;
            case Direction::down:
                return Direction::left;
            default:
                break;
        }
    }
    return Direction::count; // Invalid
}

int2 Direction::vector() const
{
    switch(m_value)
    {
        case Direction::left:
            return int2(-1,0);
        case Direction::up:
            return int2(0,-1);
        case Direction::right:
            return int2(1,0);
        case Direction::down:
            return int2(0,1);
        default:
            return int2(0,0);
    }
}

std::ostream &operator<<(std::ostream &os, const Command& c)
{
    switch(c.m_value)
    {
        case Command::left:
            return os<<"L";
        case Command::right:
            return os<<"R";
        default:
            return os<<"F";
    }
}
/* 
 * @file    enums.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:55
 */

#ifndef ENUMS_H
#define ENUMS_H

#include <ostream>

struct int2;

#define DECL_ENUM_STRUCT(_name) \
_name() : m_value(static_cast<Type>(0)) {} \
_name(Type value) : m_value(value) {} \
_name(int value) : m_value(static_cast<Type>(value)) {} \
static Type begin() { return static_cast<Type>(0); } \
static Type end() { return count; } \
_name &operator++() { m_value=static_cast<Type>(static_cast<int>(m_value)+1); return *this; } \
operator int() const { return static_cast<Type>(m_value); } \
Type m_value;

#define foreach_enum(_type,_var) for(_type _var = _type::begin(); _var<_type::end(); ++_var)

struct Command
{
    enum Type
    {
        left,
        forward,
        right,
        count
    };

    bool isValid() const { return m_value<count; }
    friend std::ostream &operator<<(std::ostream &os, const Command& c);

    DECL_ENUM_STRUCT(Command)
};

struct Direction
{
    enum Type
    {
        left,
        up,
        right,
        down,
        count
    };

    bool isValid() const { return m_value<count; }
    Command turnTo(Direction newDir) const;
    Direction applyCommand(Command c) const;
    int2 vector() const;
    DECL_ENUM_STRUCT(Direction)
};

#endif  /* ENUMS_H */
/* 
 * @file    int2.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:37
 */

#include "int2.h"
#include "enums.h"
#include "StrManip.h"

#include <vector>
#include <cmath>

int2::int2()
{
}

int2::~int2()
{
}

int2::int2(std::string const &text)
{
    std::vector<std::string> posList;
    split(text, ',', posList);
    x=atoi(posList.at(0));
    y=atoi(posList.at(1));
}

Direction int2::direction() const
{
    if(x==0 && y==0)
        return Direction::count; // Invalid
    else if(y>=std::abs(x))
        return Direction::down;
    else if(x>=std::abs(y))
        return Direction::right;
    else if(x<=-std::abs(y))
        return Direction::left;
    else
        return Direction::up;
}

Direction int2::secondary() const
{
    if(x==0 || y==0)
        return Direction::count; //Invalid
    else if(y<=std::abs(x) && y>=0)
        return Direction::down;
    else if(x<=std::abs(y) && x>=0)
        return Direction::right;
    else if(x>=-std::abs(y) && x<=0)
        return Direction::left;
    else
        return Direction::up;
}

int int2::distTo(int2 const &other) const
{
    return std::abs(x-other.x)+std::abs(y-other.y);
}

int int2::quadDistTo(int2 const &other) const
{
    return sq(x-other.x)+sq(y-other.y);
}

int2 int2::operator+(int2 const &other) const
{
    return int2(x+other.x,y+other.y);
}

int2 int2::operator-(int2 const &other) const
{
    return int2(x-other.x,y-other.y);
}

std::ostream &operator<<(std::ostream &os, const int2& c)
{
    return os<<c.x<<","<<c.y;
}

std::istream &operator>>(std::istream &is, int2& c)
{
    std::string text;
    is>>text;
    c=int2(text);
    return is;
}
/* 
 * @file    int2.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:37
 */

#ifndef INT2_H
#define INT2_H

#include "enums.h"

#include <string>

struct int2
{
public:
    int2();
    int2(int p_x, int p_y) : x(p_x), y(p_y) {}
    int2(std::string const &text);
    virtual ~int2();

public:
    Direction direction() const;
    Direction secondary() const;
    int distTo(int2 const &other) const;
    int quadDistTo(int2 const &other) const;
    int2 operator+(int2 const &other) const;
    int2 operator-(int2 const &other) const;
    bool operator==(int2 const &other) const { return x==other.x && y==other.y; }
    bool operator!=(int2 const &other) const { return x!=other.x || y!=other.y; }
    friend std::ostream &operator<<(std::ostream &os, const int2& c);
    friend std::istream &operator>>(std::istream &is, int2& c);

public:
    int x;
    int y;
};

inline int sq(int val) { return val*val; }
template<typename T>
inline void varSwitch(T &a, T &b) { T tmp=a; a=b; b=tmp; }

#endif  /* INT2_H */
/* 
 * @file    main.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:23
 */

#include "int2.h"
#include "Snake.h"
#include "Enemy.h"

#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

/*
 * @brief La fonction principale du programme.
 * @param argc Le nombre de paramètres passés en ligne de commandes.
 * @param argv La liste des paramètres passés en ligne de commandes.
 */
int main(int argc, char** argv)
{
    /* Error handling */
    if(argc<3)
    {
        cerr<<"Error : not enough arguments on the command line."<<endl;
        cout<<"F"<<endl;
        return 1;
    }

    /* Init and load */
    int2 prevFood;
    int date = 0;
    Enemy enemy;
    ifstream load("PreviousState.txt");
    if(load)
    {
        load>>date;
        load>>prevFood;
        load>>enemy;
        load.close();
    }
    int2 food(argv[1]);
    Snake me(argv[2]);
    if(me.isStarting())
    {
        date=0;
        if(me.curPos().x<MAPSIZE/2)
            enemy.setPos(int2(MAPSIZE-4,MAPSIZE/2), 0);
        else
            enemy.setPos(int2(3,MAPSIZE/2), 0);
    }
    else if(prevFood!=food && me.curPos()!=prevFood)
    {
        enemy.setPos(prevFood, date);
    }

    /* Moving */
    cout<<me.move(food,date,enemy)<<endl;

    /* Saving */
    ofstream save("PreviousState.txt");
    if(save)
    {
        save<<++date<<endl;
        save<<food<<endl;
        save<<enemy<<endl;
        save.close();
    }
    return 0;
}
# Makefile
HEADERS = $(wildcard $(SRCPATH)/*.h)
SOURCES = $(wildcard $(SRCPATH)/*.cpp)
OBJECTS = $(patsubst $(SRCPATH)/%.cpp,$(BUILDPATH)/%.o,$(SOURCES))
M = Makefile

CFLAGS = -Wall -std=c++11

BINPATH = bin
BUILDPATH = build
SRCPATH = src

ifeq ($(OS),Windows_NT)
EXE = Zen.exe
else
EXE = Zen
endif


$(BINPATH)/$(EXE): $(BINPATH) $(BUILDPATH) $(OBJECTS)
    g++ -o $@ $(OBJECTS)

$(BUILDPATH)/%.o: $(SRCPATH)/%.cpp $(HEADERS) $M
    g++ $(CFLAGS) -o $@ -c $<

$(BINPATH) $(BUILDPATH):
    mkdir $@

clean:
    rm $(OBJECTS)

또는 zip 파일을 다운로드하십시오 : Zen.zip

결과

|     Name     |   Master   | Score |
|--------------|------------|-------|
| Zen          | GholGoth21 | 24    |
| SneakySnake  | Cipher     | 10    |
| ViciousViper | Cipher     | 6     |
| CircleOfLife | Manu       | 4     |

그리고 전형적인 전투 (ViciousViper vs Zen 및 SneakySnake vs Zen) :

ViciousViper 및 젠 SneakySnake vs Zen

편집 : 나는 CircleOfLife에 대한이 매우 흥미로운 전투를 추가합니다 :

여기에 이미지 설명을 입력하십시오


좋은 전략. 다른 곳에서 더 쉽게 사용할 수 있도록 프로젝트를 압축 파일로 업로드 할 수 있습니까?
randomra

4

CircleOfLife (자바)

CircleOfLife Manu java CircleOfLife(와 컴파일 javac CircleOfLife.java)

가운데로 달려가 그곳에 머물러 있습니다. 나는 음식으로가는 도중에 일부 제출물이 충돌하기를 바랍니다.

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;  

public class CircleOfLife {
    private static final int UP = 0;
    private static final int DOWN = 1;
    private static final int LEFT = 2;
    private static final int RIGHT = 3;
    private static final String GO_RIGHT = "R";
    private static final String GO_LEFT = "L";
    private static final String GO_FORWARD = "F";
    private static int currentDirection = UP;
    private static List<Point> snakeParts = new ArrayList<>();

    public static void main(String[] args) {
        String[] parts = args[1].split("/");
        for (String part : parts) {
            String[] pos = part.split(",");
            int x = Integer.parseInt(pos[0]);
            int y = Integer.parseInt(pos[1]);
            snakeParts.add(new Point(x,y));
        }
        Point head = snakeParts.get(0);
        Point neck = snakeParts.get(1);
        if (head.y - neck.y == 1) {
            currentDirection = DOWN;
        } else if (head.x - neck.x == -1) {
            currentDirection = LEFT;
        } else if (head.x - neck.x == 1) {
            currentDirection = RIGHT;
        }
        if (isInMiddle(head)) {
            makeCircle();
        } else {
            runToMiddle();
        }
    }

    private static void makeCircle() {
        if (!isInMiddle(snakeParts.get(1))) {
            System.out.println(GO_FORWARD);
            return;
        }
        Point head = snakeParts.get(0);
        Point neck = snakeParts.get(1);
        String output = GO_FORWARD;
        if (head.x == 8 && neck.x == 8) {
            output = currentDirection == UP ? GO_LEFT : GO_RIGHT;
        } else if (head.x == 7 && neck.x == 7) {
            output = currentDirection == UP ? GO_RIGHT : GO_LEFT;           
        } else if (head.y == 8 && neck.y == 8) {
            output = currentDirection == RIGHT ? GO_LEFT : GO_RIGHT;        
        } else if (head.y == 7 && neck.y == 7) {
            output = currentDirection == RIGHT ? GO_RIGHT : GO_LEFT;        
        }
        System.out.println(output);
    }

    private static void runToMiddle() {
        Point head = snakeParts.get(0);
        int dX = 8 - head.x;
        int dY = 8 - head.y;
        String output = GO_FORWARD;

        if (Math.abs(dX) > Math.abs(dY)) {
            switch (currentDirection) {
                case DOWN: output = dX < 0 ? GO_RIGHT : GO_LEFT; break;
                case UP: output = dX < 0 ? GO_LEFT : GO_RIGHT; break;
                case RIGHT: output = dX < 0 ? GO_RIGHT : GO_FORWARD; break;
                case LEFT: output = dX < 0 ? GO_FORWARD : GO_RIGHT; break;
            }
        } else {
            switch (currentDirection) {
                case DOWN: output = dY < 0 ? GO_RIGHT : GO_FORWARD; break;
                case UP: output = dY < 0 ? GO_FORWARD : GO_RIGHT; break;
                case RIGHT: output = dY < 0 ? GO_LEFT : GO_RIGHT; break;
                case LEFT: output = dY < 0 ? GO_RIGHT : GO_LEFT; break;
            }
        }
        System.out.println(output);
    }

    public static boolean isInMiddle(Point snakePart) {
        if ((snakePart.x == 7 || snakePart.x == 8) && 
                (snakePart.y == 7 || snakePart.y == 8)) {
            return true;
        }
        return false;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.