ජාවා නොවන ඉදිරිපත් කිරීම් සඳහා එතීම
NOTE MAP_SIZE සහාය එකතු කර ඇත. ඔබ සැලකිලිමත් නම්, කරුණාකර ඔබේ ඉදිරිපත් කිරීම ඒ අනුව යාවත්කාලීන කරන්න.
මෙය එතුමිය සඳහා ප්රජා විකියකි, එය සෙල්ලම් කිරීමට කැමති නමුත් ජාවා කැමති / නොදන්නා අයට භාවිතා කළ හැකිය. කරුණාකර එය භාවිතා කරන්න, විනෝද වන්න, සහ දේවල් සකස් කර ගැනීමට ඔබට උදව් කිරීමට මම සතුටු වෙමි.
මම ඉවර වන විට මෙහි ප්රමාද වැඩියි, එබැවින් වෙනත් ජාවා කෝඩර්ස්, කරුණාකර මෙය සොයා බලා වැඩිදියුණු කිරීම් යෝජනා කරන්න. ඔබට හැකි නම්, ගැටළුවක් ගොනු කිරීමෙන් හෝ පැච් එකක් ඉදිරිපත් කිරීමෙන් මගේ ගිතුබ් ගබඩාව හරහා එසේ කරන්න. ස්තූතියි!
මේ සියල්ල UNLICENSE සමඟ බෙදා හරිනු ලැබේ, කරුණාකර එහි ගිතුබ් ගබඩාවෙන් එය අනුගමනය කරන්න . ඔබට ගැටළු ඇත්නම් පැච් එහි ඉදිරිපත් කරන්න, මම මෙම ලිපිය යාවත්කාලීන කරමි.
භාවිතයේ ඇති රැපර් සඳහා වර්තමාන උදාහරණ
plannapus : R හි WolfCollectiveMemory
භාවිතා කරන්නේ කෙසේද
පහත දැක්වෙන්නේ දුරස්ථ වෘකයන් සඳහා මා විසින් අර්ථ දක්වා ඇති PIPES හරහා අන්තර් ක්රියාදාම සන්නිවේදනය සඳහා වන ප්රොටෝකෝලය පිළිබඳ උපදෙස් ය. OP හි ගැටළු ප්රකාශයේ එය තිබියදීත්, මෙය නොපවතින බැවින් මම MAP_SIZE මඟ හැරියෙමි. එය දිස්වන්නේ නම්, මම මෙම ලිපිය යාවත්කාලීන කරමි.
වැදගත් සටහන් :
- ඔබගේ බාහිර ක්රියාවලියේ එක් ආයාචනයක් පමණක් කරනු ලැබේ (එබැවින් ඔබේ සැකසුම් තර්කනය අසීමිත පුඩුවක් තුළට ඔතා තබන්න. තැටිය භාවිතා කරනවා වෙනුවට ඕනෑම සැකසුම් මතකයේ තබා ගැනීමට මෙය ඔබට ඉඩ සලසයි)
- සියලුම සන්නිවේදනයන් STDIN සහ STDOUT හරහා මෙම තනි බාහිර ක්රියාවලියට සම්බන්ධ වේ
- STDOUT වෙත යවන ලද සියලුම ප්රතිදානයන් ඔබ පැහැදිලිවම ගලා යා යුතු අතර එය නව රේඛාව අවසන් කර ඇති බවට වග බලා ගන්න
පිරිවිතර
දුරස්ථ ස්ක්රිප්ටයට STDIN සහ STDOUT කොකු හරහා සරල ප්රොටෝකෝලයක් මඟින් සහාය වන අතර එය ආරම්භ කිරීම, ගෙනයාම සහ ප්රහාරය ලෙස බෙදා ඇත. සෑම අවස්ථාවකම ඔබේ ක්රියාවලිය සමඟ සන්නිවේදනය STDIN හරහා වන අතර STDOUT වෙතින් පිළිතුරක් අවශ්ය වේ. තත්පර 1 කින් පිළිතුරක් නොලැබුනේ නම්, ඔබේ ක්රියාවලිය මිය ගොස් ඇතැයි උපකල්පනය කර ව්යතිරේකයක් විසි කරනු ලැබේ. සියලුම අක්ෂර UTF-8 හි කේතනය කරනු ලැබේ. සෑම ආදානයක්ම නව රේඛා අක්ෂරයකින් අවසන් වන අතර ඔබේ ක්රියාවලිය සෑම ප්රතිදාන පිළිතුරක්ම නව රේඛාවක් සමඟ අවසන් කළ යුතුය.
අවවාදයයි ජාවා එතීමෙන් ඔබේ ප්රතිදානය දකින බව සහතික කිරීම සඳහා සෑම ලිවීමකටම පසුව ඔබේ ප්රතිදාන බෆරය ගලා යාමට වග බලා ගන්න. ෆ්ලෂ් කිරීමට අපොහොසත් වීම ඔබගේ දුරස්ථ වුල්ෆ් අසමත් වීමට හේතු විය හැක.
එක් ක්රියාවලියක් පමණක් නිර්මාණය වන බව සලකන්න, එම එක් ක්රියාවලියක් තුළ සියලු වෘකයන් කළමනාකරණය කළ යුතුය. මෙම පිරිවිතර උපකාරී වන්නේ කෙසේදැයි කියවන්න.
ආරම්භ කිරීම
STDIN: S<id><mapsize>
\ n
STDOUT: K<id>
\ n
<id>
: 00
හෝ 01
හෝ ... හෝ99
පැහැදිලි කිරීම:
චරිතය S
සංඛ්යාත්මක අනුලකුණු දෙකක් අනුගමනය යවනු ලැබේ 00
, 01
,, ... 99
වෘකයන් 100 වන ආරම්භනය කොට ඇත පෙන්නුම්. එම විශේෂිත වෘකයා සමඟ අනාගත සන්නිවේදනයේදී, එයම <id>
භාවිතා වේ.
හැඳුනුම්පත අනුගමනය කිරීමෙන් සංඛ්යාත්මක අක්ෂරවල විචල්ය දිග අනුක්රමයක් යවනු ලැබේ. මෙය සිතියමේ ප්රමාණයයි. ඔබ නව රේඛාවට ( \n
) ලඟා වන විට සංඛ්යාත්මක අනුක්රමය අවසන් බව ඔබ දැන ගනු ඇත .
ඔබේ ක්රියාවලිය ජීවමාන බව සහතික කිරීම සඳහා, ඔබට ලැබුණු චරිතය K
අනුගමනය කරමින් ඔබ පිළිතුරු දිය යුතුය <id>
. වෙනත් ඕනෑම පිළිතුරක ව්යතිරේකයක් ඇති වනු ඇත, ඔබේ වෘකයන් මරා දමයි.
චලනය
STDIN: M<id><C0><C1>...<C7><C8>
\ n
STDOUT: <mv><id>
\ n
<Cn>
: W
හෝ
හෝ B
හෝ S
හෝL
W
: වුල්ෆ්
: හිස් අවකාශය
B
: වලස්
S
: ගල්
L
: සිංහයා
<mv>
: H
හෝ U
හෝ L
හෝ R
හෝD
H
: චලනය කරන්න
U
: Move.UP
L
: Move.LEFT
R
: චලනය කරන්න
D
: ගෙනයන්න
පැහැදිලි කිරීම:
වුල්ෆ්ට පියවරක් තෝරා ගැනීමට අවශ්ය වන්නේ කුමක්ද යන්න දැක්වීමට M
චරිත දෙකෙන් පසුව චරිතය යවනු ලැබේ <id>
. ඊට පසු, එම වුල්ෆ්ගේ වටපිටාව පේළි අනුපිළිවෙලින් (ඉහළ පේළිය, මැද පේළිය, පහළ පේළිය වමේ සිට දකුණට) නියෝජනය කරමින් අක්ෂර 9 ක් යවනු ලැබේ.
වලංගු චලන අක්ෂර වලින් එකක් සමඟ පිළිතුරු දෙන්න <mv>
, ඉන්පසු <id>
තහවුරු කිරීම සඳහා වුල්ෆ්ගේ ඉලක්කම් දෙක අනුගමනය කරන්න .
ප්රහාරය
STDIN: A<id><C>
\ n
STDOUT: <atk><id>
\ n
<C>
: W
හෝ B
හෝ S
හෝL
<atk>
: R
හෝ P
හෝ S
හෝD
R
: ප්රහාරය . රොක්
P
: ප්රහාරය
S
: ප්රහාරය . SCISSORS
D
: ප්රහාරය
පැහැදිලි කිරීම:
වුල්ෆ් ප්රහාරයකට සහභාගී වන්නේ කුමන චරිතයටද යන්න දැක්වීමට A
චරිත දෙකෙන් පසුව චරිතය යවනු ලැබේ <id>
. ඕල්ෆ්, කණ, තානය හෝ අයන <C>
කුමන ආකාරයේ දේකට පහර W
දෙනවාද යන්න දැක්වෙන තනි අක්ෂරයකින් මෙය අනුගමනය කෙරේ .B
S
L
තහවුරු කිරීම සඳහා <atk>
ඉලක්කම් දෙකෙන් පසුව, ප්රහාරයට ඔබේ ප්රතිචාරය කුමක්දැයි දක්වමින් ඉහත ලැයිස්තුගත කර ඇති එක් අක්ෂරයකින් පිළිතුරු දෙන්න <id>
.
ඒක තමයි. ඊට තවත් දෙයක් නැත. ඔබට ප්රහාරයක් අහිමි වුවහොත්, එය <id>
නැවත කිසි දිනෙක ඔබේ ක්රියාවලියට යවනු නොලැබේ, ඔබේ වුල්ෆ් මියගොස් ඇති බව ඔබ දැනගන්නේ එලෙසයි - එය එවීමකින් තොරව සම්පූර්ණ චලන වටයක් පසු වී ඇත්නම් <id>
.
නිගමනය
කිසියම් ව්යතිරේකයක් මඟින් ඔබේ දුරස්ථ වර්ගයේ වෘකයන් සියල්ලම මරා දමන බව සලකන්න, ඔබේ දුරස්ථ වෘකයාගෙන් තනි "ක්රියාවලියක්" පමණක් ගොඩනඟා ඇති බැවින්, ඔබේ වර්ගයේ සියලුම වෘකයන් නිර්මාණය වේ.
මෙම ගබඩාවේ ඔබ Wolf.java
ගොනුව සොයා ගනු ඇත . ඔබේ බොට් සැකසීමට පහත සඳහන් නූල් සොයන්න සහ ප්රතිස්ථාපනය කරන්න:
<invocation>
ඔබේ ක්රියාවලිය නිසියාකාරව ක්රියාත්මක කරන විධාන රේඛා තර්කය සමඟ ප්රතිස්ථාපනය කරන්න .
<custom-name>
ඔබේ වුල්ෆ් සඳහා අද්විතීය නමකින් ආදේශ කරන්න .
නිදසුනක් ලෙස , මගේ උදාහරණය දුරස්ථව (පයිතන් 3+ වුල්ෆ්) ඉල්ලා සිටින ගබඩාව දෙස බලන්න .WolfRandomPython.java
PythonWolf.py
ගොනුව නැවත නම් කරන්න Wolf<custom-name>.java
, එහිදී <custom-name>
ඔබ ඉහත තෝරාගත් නම සමඟ ප්රතිස්ථාපනය වේ.
ඔබේ වුල්ෆ් පරීක්ෂා කිරීම සඳහා, ජාවා වැඩසටහන ( javac Wolf<custom-name>.java
) සම්පාදනය කර එය අනුකරණ වැඩසටහනට ඇතුළත් කිරීමට රුෂර්ගේ උපදෙස් අනුගමනය කරන්න.
වැදගත්: මම ඉහත දක්වා ඇති යෝජනා ක්රමය අනුගමනය කරන ඔබේ සැබෑ වුල්ෆ් සම්පාදනය / ක්රියාත්මක කරන්නේ කෙසේද යන්න පිළිබඳ පැහැදිලි , සංක්ෂිප්ත උපදෙස් ලබා දීමට වග බලා ගන්න .
වාසනාව, සහ ස්වභාව ධර්මය ඔබට වාසිදායක වේවා.
රැපර් කේතය
මතක තබා ගන්න, ඔබ මෙය කළ යුතු සෙවීම් කළ යුතු අතර ප්රතිස්ථාපනය කළ යුතුය. ඔබේ ආයාචනය විශේෂයෙන් කෙස් කළඹක් නම්, කරුණාකර සහාය සඳහා මා අමතන්න.
main
ඔබේ ප්රාදේශීය පෙට්ටියේ මුලික "සමත් / අසමත්" පරීක්ෂණ සඳහා ඉඩ ලබා දීම සඳහා මෙම එතුමෙහි ක්රමයක් ඇති බව සලකන්න . එසේ කිරීමට, ව්යාපෘතියෙන් Animal.java පන්තිය බාගත කර package animals;
ගොනු දෙකෙන්ම රේඛාව ඉවත් කරන්න . Animal.java හි MAP_SIZE රේඛාව නියත (100 වැනි) සමඟ ප්රතිස්ථාපනය කරන්න. javac Wolf<custom-name>.java
ක්රියාත්මක කිරීම හරහා ඒවා සම්පාදනය කරන්න java Wolf<custom-name>
.
package animals;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Remote Wolf<custom-name> wrapper class.
*/
public class Wolf<custom-name> extends Animal {
/**
* Simple test script that sends some typical commands to the
* remote process.
*/
public static void main(String[]args){
Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
for(int i=0; i<10; i++) {
wolves[i] = new Wolf<custom-name>();
}
char map[][] = new char[3][3];
for (int i=0;i<9;i++)
map[i/3][i%3]=' ';
map[1][1] = 'W';
for(int i=0; i<10; i++) {
wolves[i].surroundings=map;
System.out.println(wolves[i].move());
}
for(int i=0; i<10; i++) {
System.out.println(wolves[i].fight('S'));
System.out.println(wolves[i].fight('B'));
System.out.println(wolves[i].fight('L'));
System.out.println(wolves[i].fight('W'));
}
wolfProcess.endProcess();
}
private static WolfProcess wolfProcess = null;
private static Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
private static int nWolves = 0;
private boolean isDead;
private int id;
/**
* Sets up a remote process wolf. Note the static components. Only
* a single process is generated for all Wolves of this type, new
* wolves are "initialized" within the remote process, which is
* maintained alongside the primary process.
* Note this implementation makes heavy use of threads.
*/
public Wolf<custom-name>() {
super('W');
if (Wolf<custom-name>.wolfProcess == null) {
Wolf<custom-name>.wolfProcess = new WolfProcess();
Wolf<custom-name>.wolfProcess.start();
}
if (Wolf<custom-name>.wolfProcess.initWolf(Wolf<custom-name>.nWolves, MAP_SIZE)) {
this.id = Wolf<custom-name>.nWolves;
this.isDead = false;
Wolf<custom-name>.wolves[id] = this;
} else {
Wolf<custom-name>.wolfProcess.endProcess();
this.isDead = true;
}
Wolf<custom-name>.nWolves++;
}
/**
* If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
* Otherwise, communicate an attack to the remote process and return
* its attack choice.
*/
@Override
public Attack fight(char opponent) {
if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
return Attack.SUICIDE;
}
try {
Attack atk = Wolf<custom-name>.wolfProcess.fight(id, opponent);
if (atk == Attack.SUICIDE) {
this.isDead = true;
}
return atk;
} catch (Exception e) {
System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
isDead = true;
return Attack.SUICIDE;
}
}
/**
* If the wolf is dead, or all the wolves of this type are dead, HOLD.
* Otherwise, get a move from the remote process and return that.
*/
@Override
public Move move() {
if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
return Move.HOLD;
}
try {
Move mv = Wolf<custom-name>.wolfProcess.move(id, surroundings);
return mv;
} catch (Exception e) {
System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
isDead = true;
return Move.HOLD;
}
}
/**
* The shared static process manager, that synchronizes all communication
* with the remote process.
*/
static class WolfProcess extends Thread {
private Process process;
private BufferedReader reader;
private PrintWriter writer;
private ExecutorService executor;
private boolean running;
public boolean getRunning() {
return running;
}
public WolfProcess() {
process = null;
reader = null;
writer = null;
running = true;
executor = Executors.newFixedThreadPool(1);
}
public void endProcess() {
running = false;
}
/**
* WolfProcess thread body. Keeps the remote connection alive.
*/
public void run() {
try {
System.out.println("Starting Wolf<custom-name> remote process");
ProcessBuilder pb = new ProcessBuilder("<invocation>".split(" "));
pb.redirectErrorStream(true);
process = pb.start();
System.out.println("Wolf<custom-name> process begun");
// STDOUT of the process.
reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
System.out.println("Wolf<custom-name> reader stream grabbed");
// STDIN of the process.
writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
System.out.println("Wolf<custom-name> writer stream grabbed");
while(running){
this.sleep(0);
}
reader.close();
writer.close();
process.destroy(); // kill it with fire.
executor.shutdownNow();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wolf<custom-name> ended catastrophically.");
}
}
/**
* Helper that invokes a read with a timeout
*/
private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
Callable<String> readTask = new Callable<String>() {
@Override
public String call() throws Exception {
return reader.readLine();
}
};
Future<String> future = executor.submit(readTask);
return future.get(timeout, TimeUnit.MILLISECONDS);
}
/**
* Sends an initialization command to the remote process
*/
public synchronized boolean initWolf(int wolf, int map_sz) {
while(writer == null){
try {
this.sleep(0);
}catch(Exception e){}
}
boolean success = false;
try{
writer.printf("S%02d%d\n", wolf, map_sz);
writer.flush();
String reply = getReply(5000l);
if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
success = true;
}
}
if (reply == null) {
System.out.println("did not get reply");
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to initialize, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to initialize, %s\n", wolf, e.getMessage());
}
return success;
}
/**
* Send an ATTACK command to the remote process.
*/
public synchronized Attack fight(int wolf, char opponent) {
Attack atk = Attack.SUICIDE;
try{
writer.printf("A%02d%c\n", wolf, opponent);
writer.flush();
String reply = getReply(1000l);
if (reply.length() >= 3) {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
switch(reply.charAt(0)) {
case 'R':
atk = Attack.ROCK;
break;
case 'P':
atk = Attack.PAPER;
break;
case 'S':
atk = Attack.SCISSORS;
break;
case 'D':
atk = Attack.SUICIDE;
break;
}
}
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to attack, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to attack, %s\n", wolf, e.getMessage());
}
return atk;
}
/**
* Send a MOVE command to the remote process.
*/
public synchronized Move move(int wolf, char[][] map) {
Move move = Move.HOLD;
try{
writer.printf("M%02d", wolf);
for (int row=0; row<map.length; row++) {
for (int col=0; col<map[row].length; col++) {
writer.printf("%c", map[row][col]);
}
}
writer.print("\n");
writer.flush();
String reply = getReply(1000l);
if (reply.length() >= 3) {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
switch(reply.charAt(0)) {
case 'H':
move = Move.HOLD;
break;
case 'U':
move = Move.UP;
break;
case 'L':
move = Move.LEFT;
break;
case 'R':
move = Move.RIGHT;
break;
case 'D':
move = Move.DOWN;
break;
}
}
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to move, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to move, %s\n", wolf, e.getMessage());
}
return move;
}
}
}