সংক্ষিপ্ত বিবরণ
কে সবচেয়ে বেশি দীর্ঘস্থায়ী হতে পারে তা দেখার জন্য এটি একটি বট যুদ্ধ। এই বটগুলি আক্রমণের দ্বারা তাদের শক্তি বাড়ায়, যদিও, গুলি করার আগে আপনাকে সাবধানে চিন্তা করা দরকার
প্রতিটি পালা, আপনি আক্রমণ করতে বা প্রতিরক্ষা করতে একটি বট বেছে নিতে পারেন। আক্রমণ তার জীবনকে কমিয়ে দেবে এবং এর শক্তি বাড়িয়ে তুলবে। শেষ বট স্থায়ী জয়।
বট
প্রতিটি বট 1000 জীবন এবং 10 শক্তি দিয়ে শুরু হয়।
যখন আক্রমণ করা হয়:
- আপনার আক্রমণকারীর শক্তি আপনার জীবন থেকে বিয়োগ করা হয়েছে
- আপনার শক্তি 1 দ্বারা উত্থাপিত হয়।
সুতরাং, প্রথম বারে যদি আপনি দুটি বট আক্রমণ করেন তবে আপনার 980 জীবন এবং 12 শক্তি থাকবে।
আপনি যদি রক্ষা করতে চান:
- আপনার শক্তি 1 দ্বারা হ্রাস করা হবে
- আপনার বিরুদ্ধে সমস্ত আক্রমণ এই পালা অর্ধেকে হ্রাস পাবে
- যদি আপনার উপর আক্রমণ করা হয় তবে আপনি 1 এর পরিবর্তে প্রতিটি আক্রমণকারীর জন্য 2 শক্তি অর্জন করবেন
সুতরাং, আপনি যদি প্রথম বারে প্রতিরক্ষা করেন এবং দুটি বট আক্রমণ করেন তবে আপনার 990 জীবন এবং 13 শক্তি থাকবে। আপনি যদি প্রতিরক্ষা করেন এবং আক্রমণ না করা হয় তবে আপনার 1000 জীবন থাকবে তবে 9 শক্তি থাকবে।
যদি কোনও বাঁক শেষে আপনার পাওয়ার একের নীচে থাকে তবে এটি একটিতে সেট করা হবে। আপনার জীবন যদি 1 এর নীচে থাকে তবে আপনি মারা যান।
ইনপুট আউটপুট
প্রতি ঘুরে একবার বুট বলা হয়। প্রতিটি টার্নের জন্য এক সেকেন্ডের সময়সীমা থাকে।
প্রাথমিক
আপনার বটটিকে প্রথমবার ডাকা হলে এটি কোনও আর্গুমেন্ট দেওয়া হবে না। সাড়া ok
। আপনার বট প্রতিক্রিয়া জানায় তা নিশ্চিত করার জন্য এটি করা হয়। এটি না হলে এটি প্লেয়ার তালিকায় যুক্ত হবে না।
প্রতিটি পালা
প্রতিটি মোড়, আপনার বট কমান্ড লাইন আর্গুমেন্ট হিসাবে গেমের সমস্ত বট সম্পর্কে তথ্য দেওয়া হয়। এই যুক্তিগুলির একটি উদাহরণ:
1 0,1000,10,1 1,995,11,D
প্রথম যুক্তিটি হ'ল আপনার বটের অনন্য আইডি। তারপরে, বটগুলির একটি পৃথক পৃথক তালিকা উপস্থিত হয়। প্রতিটি বট এই রূপে ফর্ম্যাট করা হয়:
id,life,power,lastAction
lastAction
তারা কোন বোট আক্রমণ করেছে, D
যদি তারা রক্ষা করে, এবং X
যদি এটি প্রথম বার হয় তবে প্রতিনিধিত্বকারী একটি পূর্ণসংখ্যা হতে পারে । অন্যরা সবাই পূর্ণসংখ্যার হয়।
সুতরাং উপরের উদাহরণে, আপনি বট 1
এবং আপনার শেষ পালা থেকে রক্ষিত। বট 0
আপনাকে আক্রমণ করেছে এবং এখনও স্বাস্থ্য / শক্তি শুরু করছে।
প্রতিটি পালা জন্য আউটপুট খুব সহজ। আপনি যে সংখ্যক পূর্ণসংখ্যার (যেমন 0
বা 3
) হিসাবে আক্রমণ করতে চান বা D
রক্ষা করতে চান তা কেবল আউটপুট করুন । মৃত বা অস্তিত্বহীন বটগুলিতে আক্রমণ করবেন না, কারণ এটি একটি অবৈধ আদেশ হিসাবে গণ্য। যে কোনও অবৈধ কমান্ডের ফলে আপনি 1 পাওয়ার হারাবেন।
টুর্নামেন্ট কাঠামো
প্রতিটি গেমটিতে 1000 স্বাস্থ্য এবং 10 পাওয়ার থেকে শুরু হওয়া সমস্ত বট থাকে। সমস্ত বট দ্বারা ক্রিয়া একসাথে নেওয়া হয়। গেমের সর্বাধিক সংখ্যক টার্নের সংখ্যা 1000
যদি মোড় শেষে একটি বট জীবিত থাকে (জীবন> 0), এটি এক পয়েন্ট করে এবং অন্য একটি খেলা শুরু হয়। যদি টার্ন সীমাটি পৌঁছে যায় এবং একাধিক বট জীবিত থাকে তবে কেউ বিন্দু পায় না। যদি সমস্ত অবশিষ্ট বট একই টার্নে মারা যায় তবে কেউ পয়েন্ট পায় না।
একটি টুর্নামেন্টে 15 টি খেলা রয়েছে। যার শেষে সবচেয়ে বেশি পয়েন্ট রয়েছে সে জিতবে! প্রতিটি জয়যুক্ত খেলায় জীবনের যোগফলের সাথে সম্পর্কগুলি ভেঙে যায়।
রাষ্ট্র
বটগুলি কেবল নিজের নামে থাকা কোনও একক ফাইল থেকে পড়তে বা লিখতে পারে, নামের একটি সরাসরি সাবফোল্ডারে state
("হিরো" লিখতে পারে state/hero.whatever
)। এই ফাইলটির আকার 1024 2 বাইটের বেশি হওয়া উচিত নয় । সময় সীমা নিরীক্ষণ যত্ন নিন। আপনার প্রোগ্রামটি গণনা করার জন্য এক সেকেন্ডের মধ্যে শেষ হতে হবে , কেবল কোনও প্রতিক্রিয়া নয়।
এই ফাইলগুলি প্রতিটি টুর্নামেন্টের আগে মুছে ফেলা হবে তবে গেমটি অব্যাহত থাকবে। সমস্ত বট সনাক্তকারী ( id
) এছাড়াও গেমসের মধ্যে একই থাকবে।
নিয়ামক
নীচে টুর্নামেন্টের নিয়ন্ত্রক ( Stronger.java
) রয়েছে। ডিফল্টরূপে , এটি কেবলমাত্র চূড়ান্ত ফলাফল (প্লেয়ারদের বাছাই করা তালিকা, শীর্ষে বিজয়ী) আউটপুট দেয়, এতে বেশ কিছুটা সময় লাগতে পারে। এটি হিমশীতল নয়, নিরব মাত্র। আপনি যদি আরও বিশদভাবে টার্ন বাই টার্ন আউটপুট চান, -log
চলমান অবস্থায় যুক্তি যুক্ত করুন ।
বট যোগ করতে আপনার কাছে দুটি বিকল্প রয়েছে:
আর্গুমেন্ট হিসাবে কমান্ড যুক্ত করুন (
java Stronger -log "python bot.py"
)উত্সটিতে কমান্ড যুক্ত করুন
defaultPlayers[]
("python bot.py"
)
বোট, হিরো , বুলি এবং কাওয়ার্ড এই উত্তরটি পাওয়া যাবে এবং স্কোরিংয়ের উদ্দেশ্যে ব্যবহার করা হবে।
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Stronger {
static final String[] defaultPlayers = {
"java Hero",
"java Bully",
"java Coward"
};
final int timeout = 1000;
final int startLife = 1000;
final int startPower = 10;
final int numRounds = 15;
boolean log = false;
List<Player> players;
public static void main(String[] args){
new Stronger().run(args);
}
void run(String[] args){
init(args);
for(int i=0;i<numRounds;i++){
Collections.shuffle(players);
runGame();
}
Collections.sort(players);
for(Player player : players)
System.out.println(player.toString());
}
void runGame(){
log("Player Count: " + players.size());
for(Player player : players)
player.reset();
int turn = 0;
while(turn++ < startLife){
if(aliveCount() < 2)
break;
log("Turn " + turn);
List<Player> clones = new ArrayList<Player>();
for(Player player : players)
clones.add(player.copy());
for(Player player : players){
if(player.life < 1 || player.timedOut)
continue;
String[] args = new String[players.size()+1];
args[0] = "" + player.id;
for(int i=1;i<args.length;i++)
args[i] = players.get(i-1).toArgument();
String reply = getReply(player, args);
Player clone = player.findCopyOrMe(clones);
if(reply.equals("T")){
clone.timedOut = true;
clone.life = 0;
}
clone.lastAction = reply.trim();
}
for(Player player : players){
if(player.life < 1 || player.timedOut)
continue;
Player clone = player.findCopyOrMe(clones);
if(clone.lastAction.equals("D")){
clone.power--;
}else{
try{
int target = Integer.parseInt(clone.lastAction);
for(Player t : players)
if(t.id == target && t.life < 1)
throw new Exception();
for(Player tclone : clones){
if(tclone.id == target){
int atk = player.power;
if(tclone.lastAction.equals("D")){
atk -= player.power / 2;
tclone.power++;
}
tclone.life -= atk;
tclone.power++;
}
}
} catch (Exception e){
log(player.cmd + " returned an invalid command: (" + clone.lastAction + ")");
clone.power--;
}
}
}
players = clones;
for(Player player : players){
if(player.power < 1)
player.power = 1;
log(player.life + "\t\t" + player.power + "\t\t(" + player.id + ")\t" + player.cmd);
}
log("\n");
}
if(aliveCount() == 1)
for(Player player : players)
if(player.life > 0){
player.scoreRounds++;
player.scoreLife += player.life;
}
}
void log(String msg){if(log)System.out.println(msg);}
String getReply(Player player, String[] args){
try{
List<String> cmd = new ArrayList<String>();
String[] tokens = player.cmd.split(" ");
for(String token : tokens)
cmd.add(token);
for(String arg : args)
cmd.add(arg);
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.redirectErrorStream();
long start = System.currentTimeMillis();
Process process = builder.start();
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
String reply = scanner.nextLine();
scanner.close();
process.destroy();
if(System.currentTimeMillis() - start > timeout)
return "T";
return reply;
}catch(Exception e){
e.printStackTrace();
return "Exception: " + e.getMessage();
}
}
void init(String[] args){
players = new ArrayList<Player>();
for(String arg : args){
if(arg.toLowerCase().startsWith("-log")){
log = true;
}else{
Player player = createPlayer(arg);
if(player != null)
players.add(player);
}
}
for(String cmd : defaultPlayers){
Player player = createPlayer(cmd);
if(player != null)
players.add(player);
}
}
Player createPlayer(String cmd){
Player player = new Player(cmd);
String reply = getReply(player, new String[]{});
log(player.cmd + " " + reply);
if(reply != null && reply.equals("ok"))
return player;
return null;
}
int aliveCount(){
int alive = 0;;
for(Player player : players)
if(player.life > 0)
alive++;
return alive;
}
static int nextId = 0;
class Player implements Comparable<Player>{
int id, life, power, scoreRounds, scoreLife;
boolean timedOut;
String cmd, lastAction;
Player(String cmd){
this.cmd = cmd;
id = nextId++;
scoreRounds = 0;
scoreLife = 0;
reset();
}
public Player copy(){
Player copy = new Player(cmd);
copy.id = id;
copy.life = life;
copy.power = power;
copy.scoreRounds = scoreRounds;
copy.scoreLife = scoreLife;
copy.lastAction = lastAction;
return copy;
}
void reset(){
life = startLife;
power = startPower;
lastAction = "X";
timedOut = false;
}
Player findCopyOrMe(List<Player> copies){
for(Player copy : copies)
if(copy.id == id)
return copy;
return this;
}
public int compareTo(Player other){
if(scoreRounds == other.scoreRounds)
return other.scoreLife - scoreLife;
return other.scoreRounds - scoreRounds;
}
public String toArgument(){
return id + "," + life + "," + power + "," + lastAction;
}
public String toString(){
String out = "" + scoreRounds + "\t" + scoreLife;
while(out.length() < 20)
out += " ";
return out + "(" + id + ")\t" + cmd;
}
}
}
বিধি
আপনি দুটি বট পর্যন্ত প্রবেশ করতে পারেন । যদি আপনি কোনও তৃতীয় প্রবেশের জন্য প্লে থেকে অপসারণ করতে চান তবে দয়া করে এর পোস্টটি মুছুন।
আপনি মেটা-বিশ্লেষণ করে কোনও বটকে লক্ষ্য বা অন্যথায় লক্ষ্য করতে পারেন না। আপনার বট দেওয়া তথ্য ব্যবহার করুন। এটিতে আপনার নিজের বট অন্তর্ভুক্ত রয়েছে, সুতরাং আপনি দুটি বট প্রবেশ করতে পারবেন না যা সমবেত হয়।
কোনওভাবেই নিয়ামক বা অন্যান্য বটগুলির দৌড়াতে হস্তক্ষেপের চেষ্টা করবেন না।
আপনার বট তাত্ক্ষণিকভাবে বা অন্যথায় নিয়ামক বা অন্যান্য বট চালাতে পারে না।
ফলাফল
(2015-05-22 00: 00: 00Z হিসাবে জমা দেওয়া বটগুলির মধ্যে)
খেলার দুটি দফায় কিছুটা ভাল হয়েছে, মাত্র দুটি গেমটি 1000 টার্নে স্টল আউট হয়েছিল। কুলোস থেকে র্যাল্ফ মার্শালের সানতায়ানায় , যা প্রথম স্থান অর্জন করেছিল, একমাত্র বট যা তিনটি জয় পেয়েছিল। যে যথেষ্ট ছিল না, তাই সে এছাড়াও তৃতীয় স্থান গ্রহণ সুদক্ষ । স্টর্মক্রো ফ্যান্টম মেনেসের সাথে দ্বিতীয়টি নিয়েছিল , এখানে একটি সূক্ষ্ম প্রথম পোস্ট। পাঁচটি কম পোস্টের লোকদের কাছে শীর্ষ ছয়টি জায়গা নিয়ে আমাদের সব মিলিয়ে নতুন সদস্যদের দ্বারা খুব সুন্দর প্রদর্শন করা হয়েছিল। অভিনন্দন, এবং সাইটে আপনাকে স্বাগতম!
শূন্যের জয় অর্জনকারী বটগুলি স্থান বাঁচানোর জন্য তালিকাভুক্ত করা হয় না। উপরের টাইমস্ট্যাম্পটি চালানোর আগে পোস্ট করা সমস্ত বট, সুতরাং আপনি যদি নিজেরটি না দেখেন তবে এটি কিছুই জিতেনি।
Wins Life(tiebreaker) Name
3 561 perl Santayana.pl
2 850 java PhantomMenace
2 692 perl Tactician.pl
2 524 java Wiisniper
1 227 java Tank
1 184 java Velociraptor
1 7 java Coward
1 3 java IKnowYou
Sorta স্কেচি সমান্তরাল নিয়ন্ত্রক ( অন্যদের দ্বারা ):
import java.lang.ProcessBuilder.Redirect;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
public class Stronger {
static final String[] defaultPlayers = {
"java Hero",
"java Bully",
"java Coward",
"java Psycho",
"./monte.out",
"java Analyst",
"java Guardian",
"java Revenger",
"python precog.py",
//"python snappingTurtle.py",
"python beserker.py",
"./suprise.out",
//"python boxer.py",
"python defense.py",
"java Tank",
"java IKnowYou",
//"java BroBot",
"java Equaliser",
"java Velociraptor",
//"java AboveAverage",
"java PhantomMenace",
"java Wiisniper",
//"python semiRandom.py",
"/usr/bin/perl tactition.pl",
"/usr/bin/perl santayana.pl",
//"java GlitchUser"
"/usr/local/bin/Rscript opportunity.R",
"/usr/local/bin/scala Bandwagoner",
};
final int timeout = 5000;
final int startLife = 1000;
final int startPower = 10;
final int numRounds = 20;
boolean log = true;
List<Player> players;
public static void main(String[] args){
new Stronger().run(args);
}
void run(String[] args){
init(args);
for(int i=1;i<=numRounds;i++){
if(log) System.out.println("Begining round "+ i);
Collections.shuffle(players);
runGame();
}
Collections.sort(players);
for(Player player : players)
System.out.println(player.toString());
}
void runGame(){
log("Player Count: " + players.size());
for(Player player : players)
player.reset();
int turn = 0;
while(turn++ < startLife){
if(aliveCount() < 2)
break;
log("Turn " + turn);
List<Player> clones = new ArrayList<Player>();
for(Player player : players)
clones.add(player.copy());
AtomicInteger count=new AtomicInteger(players.size());
for(Player player : players){
new Thread(() -> {
if(player.life >= 1 && !player.timedOut){
String[] args = new String[players.size()+1];
args[0] = "" + player.id;
for(int i=1;i<args.length;i++)
args[i] = players.get(i-1).toArgument();
String reply = getReply(player, args);
Player clone = player.findCopyOrMe(clones);
if(reply.equals("T")){
clone.timedOut = true;
clone.life = 0;
}
clone.lastAction = reply.trim();
}
synchronized(count){
count.decrementAndGet();
count.notify();
}
}).start();
}
synchronized(count){
while(count.get() > 0){
//System.out.println(count);
try{
count.wait();
}catch(InterruptedException e){
}
}
}
for(Player player : players){
if(player.life < 1 || player.timedOut)
continue;
Player clone = player.findCopyOrMe(clones);
if(clone.lastAction.equals("D")){
clone.power--;
}else{
try{
int target = Integer.parseInt(clone.lastAction);
for(Player t : players)
if(t.id == target && t.life < 1)
throw new Exception();
for(Player tclone : clones){
if(tclone.id == target){
int atk = player.power;
if(tclone.lastAction.equals("D")){
atk -= player.power / 2;
tclone.power++;
}
tclone.life -= atk;
tclone.power++;
}
}
} catch (Exception e){
log(player.cmd + " returned an invalid command: (" + clone.lastAction + ")");
clone.power--;
}
}
}
players = clones;
for(Player player : players){
if(player.power < 1)
player.power = 1;
log(player.life + "\t\t" + player.power + "\t\t" + player.lastAction + "\t\t(" + player.id + ")\t" + player.cmd);
}
log("\n");
}
if(aliveCount() == 1)
for(Player player : players)
if(player.life > 0){
player.scoreRounds++;
player.scoreLife += player.life;
}
}
void log(String msg){if(log)System.out.println(msg);}
String getReply(Player player, String[] args){
try{
List<String> cmd = new ArrayList<String>();
String[] tokens = player.cmd.split(" ");
for(String token : tokens)
cmd.add(token);
for(String arg : args)
cmd.add(arg);
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.directory(FileSystems.getDefault().getPath(".", "bin").toFile());
//builder.redirectError(Redirect.PIPE);
long start = System.currentTimeMillis();
Process process = builder.start();
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
String reply = scanner.nextLine();
scanner.close();
process.destroy();
if(System.currentTimeMillis() - start > timeout)
return "T";
return reply;
}catch(Exception e){
//e.printStackTrace();
return "Exception: " + e.getMessage();
}
}
void init(String[] args){
players = new ArrayList<Player>();
for(String arg : args){
if(arg.toLowerCase().startsWith("-log")){
log = true;
}else{
Player player = createPlayer(arg);
if(player != null)
players.add(player);
}
}
for(String cmd : defaultPlayers){
Player player = createPlayer(cmd);
if(player != null)
players.add(player);
}
}
Player createPlayer(String cmd){
Player player = new Player(cmd);
String reply = getReply(player, new String[]{});
log(player.cmd + " " + reply);
if(reply != null && reply.equals("ok"))
return player;
return null;
}
int aliveCount(){
int alive = 0;;
for(Player player : players)
if(player.life > 0)
alive++;
return alive;
}
static int nextId = 0;
class Player implements Comparable<Player>{
int id, life, power, scoreRounds, scoreLife;
boolean timedOut;
String cmd, lastAction;
Player(String cmd){
this.cmd = cmd;
id = nextId++;
scoreRounds = 0;
scoreLife = 0;
reset();
}
public Player copy(){
Player copy = new Player(cmd);
copy.id = id;
copy.life = life;
copy.power = power;
copy.scoreRounds = scoreRounds;
copy.scoreLife = scoreLife;
copy.lastAction = lastAction;
return copy;
}
void reset(){
life = startLife;
power = startPower;
lastAction = "X";
timedOut = false;
}
Player findCopyOrMe(List<Player> copies){
for(Player copy : copies)
if(copy.id == id)
return copy;
return this;
}
public int compareTo(Player other){
if(scoreRounds == other.scoreRounds)
return other.scoreLife - scoreLife;
return other.scoreRounds - scoreRounds;
}
public String toArgument(){
return id + "," + life + "," + power + "," + lastAction;
}
public String toString(){
String out = "" + scoreRounds + "\t" + scoreLife;
while(out.length() < 20)
out += " ";
return out + "(" + id + ")\t" + cmd;
}
}
}