अपने लिए आखिरी गोली बचाएं


51

मुकाबला अब खत्म हो चुका है। कायर विजेता है। आप यहां आखिरी मैच देख सकते हैं

अचानक लाश दिखाई देती है! अरे नहीं!

इस राजा की पहाड़ी चुनौती में, आपको ज़ोंबी सर्वनाश से बचने के लिए एक बॉट बनाना होगा। या कम से कम, यथासंभव लंबे समय के लिए बाहर पकड़ो।

खेल की शुरुआत में, प्रत्येक प्रविष्टि के 50 उदाहरणों को एक बड़े टॉराइडल प्ले एरिया में बेतरतीब ढंग से रखा जाएगा - अर्थात, यह चौकोर प्रतीत होता है, लेकिन चारों ओर लपेटता है। खेल क्षेत्र का आकार प्रविष्टियों की संख्या के आधार पर अलग-अलग होगा, लेकिन शुरू में 6% वर्गों पर कब्जा होगा। प्रत्येक प्रतियोगी 3 गोलियों से शुरू होता है।

प्रत्येक मोड़ की शुरुआत में, एक ज़ोंबी एक यादृच्छिक स्थान पर जमीन से उठेगा, जो भी इसके ऊपर था, उसे नष्ट कर देगा। कोई भी खिलाड़ी जो अपनी बारी की शुरुआत में एक ज़ोंबी के बगल में है, एक ज़ोंबी बन जाएगा।

प्रत्येक जीवित खिलाड़ी के लिए, फिर उनका कोड कहा जाएगा। यह एक PlayerContext ऑब्जेक्ट प्राप्त करेगा , जिसमें उनकी वर्तमान स्थिति और उनके परिवेश की जानकारी होगी। प्रत्येक खिलाड़ी किसी भी दिशा में 8 वर्गों के लिए देख सकता है।

खिलाड़ी को या तो स्थानांतरित करने के लिए चुनना चाहिए (अभी भी एक वैध आंदोलन है), लौटने से Move, या पास के व्यक्ति या ज़ोंबी को गोली मारकर, एक को वापस करके Shoot। आपकी बंदूक में अधिकतम 5 वर्ग हैं। चूंकि आप अपनी बंदूक की सीमा के भीतर हैं तो आप खुद को गोली मार सकते हैं , बशर्ते आपके पास गोलियां बची हों। अगर दो खिलाड़ी एक दूसरे को गोली मारते हैं, तो वे दोनों मर जाते हैं।

यदि दो खिलाड़ी एक ही वर्ग में जाने का प्रयास करते हैं, तो वे असफल हो जाएंगे, और दोनों उस वर्ग में वापस आ जाएंगे, जहाँ से उन्होंने शुरुआत की थी। यदि अभी भी संघर्ष हैं, तो यह तब तक दोहराया जाएगा जब तक कोई संघर्ष नहीं होता है, जिसका अर्थ हो सकता है कि हर कोई वापस आ गया है जहां उन्होंने शुरू किया था।

यदि कोई खिलाड़ी बंदूक की गोली से मर जाता है, तो उनका मृत शरीर रह जाएगा, और एक स्थायी बाधा बन जाएगा। जो भी गोलियां वे ले जा रहे थे, वे उनके व्यक्ति पर बनी हुई थीं, और बगल के चौकों में खिलाड़ियों द्वारा छीनी जा सकती थीं। यदि किसी शव के आस-पास के चौकों पर कब्जे वाले कई खिलाड़ी हैं, तो गोलियों को उनके बीच साझा किया जाएगा, लेकिन कोई भी शेष खो जाएगा।

यदि कोई खिलाड़ी ज़ोंबी बन जाता है, तो उनकी गोलियां गुम हो जाती हैं। लाश निडरता से निकटतम जीवित खिलाड़ी की ओर चलेगी।

प्रविष्टियां इस बात पर की जाती हैं कि उनका सबसे लंबा खिलाड़ी कब तक जीवित रहता है।

प्रविष्टियां

एक नियंत्रण कार्यक्रम https://github.com/jamespic/zchin पर उपलब्ध है । बस इसे क्लोन करें, और चलाएं mvn compile exec:java

पात्र होने के लिए, प्रविष्टियों को एक जेवीएम भाषा में लिखा जाना चाहिए, पोर्टेबल होना चाहिए, और मावेन से कोई विशेष सेट-अप के साथ निर्माण करना संभव होना चाहिए। यह सुनिश्चित करना है कि प्रतियोगियों को प्रतियोगियों के खिलाफ अपने बॉट्स का परीक्षण करने के लिए कई रन-टाइम वातावरण स्थापित करने की आवश्यकता नहीं है।

नमूना प्रविष्टियाँ वर्तमान में निम्नलिखित भाषाओं में उपलब्ध हैं:

यदि आप एक ऐसी भाषा में प्रतिस्पर्धा करना चाहते हैं जो सूचीबद्ध नहीं है, तो आप एक टिप्पणी पोस्ट कर सकते हैं, जिसमें मैं अनुरोध कर सकता हूं और मैं आपकी चुनी हुई भाषा को नियंत्रण कार्यक्रम में एकीकृत करने की संभावना की जांच करूंगा। या, यदि आप अधीर हैं, तो आप नियंत्रण कार्यक्रम के लिए एक पुल अनुरोध प्रस्तुत कर सकते हैं।

प्रत्येक प्रविष्टि के लिए केवल एक उदाहरण (शब्द के जावा अर्थ में) बनाया जाएगा। इस जावा उदाहरण को प्रति बार कई बार - प्रत्येक जीवित खिलाड़ी के लिए एक बार कहा जाएगा।

एपीआई

package zombie

// You implement this. Your entry should be in package `player`
interface Player {
    Action doTurn(PlayerContext context)
}

// These already exist
class PlayerContext {
    // A square array, showing the area around you, with you at the centre
    // playFields is indexed by x from West to East, then y from North to South
    PlayerId[][] getPlayField()
    int getBullets() // Current bullets available
    int getGameClock() // Current turn number
    PlayerId getId() // Id of the current player instance
    int getX() // Your current x co-ordinate
    int getY() // Your current y co-ordinate
    int getBoardSize() // The size of the current playing field
    Set<PlayerId> shootablePlayers() // A helper function that identifies players in range.
}

class PlayerId {
    String getName() // The name of the entrant that owns this player
    int getNumber() // A unique number, assigned to this player
}

// Don't implement this. Use either `Move` or `Shoot`
interface Action {}

enum Move implements Action {
    NORTHWEST, NORTH, NORTHEAST,
    EAST, STAY, WEST,
    SOUTHEAST, SOUTH, SOUTHWEST;
    static move randomMove();
}

class Shoot implements Action {
    Shoot(PlayerId target);
}

अतिरिक्त नियम

नियंत्रण कार्यक्रम के साथ सही ढंग से काम करने के लिए प्रत्येक प्रविष्टि का एक अद्वितीय नाम होना चाहिए।

प्रविष्टियों को अन्य प्रवेशकों के साथ, या नियंत्रण कार्यक्रम के साथ छेड़छाड़ करने का प्रयास नहीं करना चाहिए, या अन्यथा रन-टाइम वातावरण का लाभ उठाने के लिए "चौथी दीवार को तोड़ना" चाहिए, और एक लाभ प्राप्त करें जो "वास्तविक" ज़ोंबी सर्वनाश में उपलब्ध नहीं होगा ।

खिलाड़ियों के बीच संवाद की अनुमति है।

विजेता वह प्रवेशक है जिसका बॉट एक परीक्षण में उच्चतम स्कोर है जो मैं 3 अगस्त 2014 को चलाऊंगा।

अंतिम परिणाम

अंतिम परिणाम में हैं! कायर विजेता है!

2 अगस्त को, मैंने नियंत्रण कार्यक्रम के 19 दौर चलाए, और प्रत्येक खिलाड़ी को उनके औसत अंक के अनुसार रैंक दिया। परिणाम निम्नवत थे:

Coward: 4298
Fox: 3214
Shotguneer: 2471
Cocoon: 1834
JohnNash: 1240
HuddleWolf: 1112
Sokie: 1090
SOS: 859
GordonFreeman: 657
Jack: 657
Waller: 366
SuperCoward: 269
MoveRandomly: 259
StandStill: 230
Vortigaunt: 226
ThePriest: 223
Bee: 61
HideyTwitchy: 52
ZombieHater: 31
Gunner: 20
ZombieRightsActivist: 16
SunTzu: 11
EmoWolfWithAGun: 0

यहां देखने के लिए अंतिम दौर उपलब्ध है

रन-बाय-रन परिणाम

19 रनों में से प्रत्येक के व्यक्तिगत परिणाम थे:

#Run at 03-Aug-2014 14:45:35#
Bee: 21
Cocoon: 899
Coward: 4608
EmoWolfWithAGun: 0
Fox: 3993
GordonFreeman: 582
Gunner: 18
HideyTwitchy: 37
HuddleWolf: 2836
Jack: 839
JohnNash: 956
MoveRandomly: 310
SOS: 842
Shotguneer: 2943
Sokie: 937
StandStill: 250
SunTzu: 3
SuperCoward: 318
ThePriest: 224
Vortigaunt: 226
Waller: 258
ZombieHater: 41
ZombieRightsActivist: 10

#Run at 03-Aug-2014 14:56:48#
Bee: 97
Cocoon: 3073
Coward: 5699
EmoWolfWithAGun: 0
Fox: 4305
GordonFreeman: 1252
Gunner: 24
HideyTwitchy: 25
HuddleWolf: 3192
Jack: 83
JohnNash: 1195
MoveRandomly: 219
SOS: 884
Shotguneer: 3751
Sokie: 1234
StandStill: 194
SunTzu: 69
SuperCoward: 277
ThePriest: 884
Vortigaunt: 564
Waller: 1281
ZombieHater: 10
ZombieRightsActivist: 2

#Run at 03-Aug-2014 15:01:37#
Bee: 39
Cocoon: 2512
Coward: 2526
EmoWolfWithAGun: 0
Fox: 2687
GordonFreeman: 852
Gunner: 21
HideyTwitchy: 91
HuddleWolf: 1112
Jack: 1657
JohnNash: 944
MoveRandomly: 312
SOS: 660
Shotguneer: 1067
Sokie: 1356
StandStill: 169
SunTzu: 8
SuperCoward: 351
ThePriest: 223
Vortigaunt: 341
Waller: 166
ZombieHater: 25
ZombieRightsActivist: 47

#Run at 03-Aug-2014 15:08:27#
Bee: 27
Cocoon: 2026
Coward: 3278
EmoWolfWithAGun: 0
Fox: 2677
GordonFreeman: 611
Gunner: 16
HideyTwitchy: 11
HuddleWolf: 1694
Jack: 600
JohnNash: 1194
MoveRandomly: 48
SOS: 751
Shotguneer: 5907
Sokie: 1233
StandStill: 62
SunTzu: 9
SuperCoward: 252
ThePriest: 173
Vortigaunt: 107
Waller: 276
ZombieHater: 53
ZombieRightsActivist: 38

#Run at 03-Aug-2014 15:14:01#
Bee: 26
Cocoon: 1371
Coward: 5121
EmoWolfWithAGun: 0
Fox: 3878
GordonFreeman: 464
Gunner: 29
HideyTwitchy: 130
HuddleWolf: 955
Jack: 101
JohnNash: 698
MoveRandomly: 269
SOS: 1314
Shotguneer: 2444
Sokie: 3217
StandStill: 233
SunTzu: 10
SuperCoward: 269
ThePriest: 318
Vortigaunt: 266
Waller: 494
ZombieHater: 49
ZombieRightsActivist: 9

#Run at 03-Aug-2014 15:19:43#
Bee: 25
Cocoon: 2098
Coward: 4855
EmoWolfWithAGun: 0
Fox: 4081
GordonFreeman: 227
Gunner: 43
HideyTwitchy: 28
HuddleWolf: 2149
Jack: 1887
JohnNash: 1457
MoveRandomly: 117
SOS: 1068
Shotguneer: 4272
Sokie: 636
StandStill: 53
SunTzu: 9
SuperCoward: 209
ThePriest: 220
Vortigaunt: 227
Waller: 366
ZombieHater: 19
ZombieRightsActivist: 49

#Run at 03-Aug-2014 15:24:03#
Bee: 46
Cocoon: 682
Coward: 3588
EmoWolfWithAGun: 0
Fox: 4169
GordonFreeman: 764
Gunner: 13
HideyTwitchy: 21
HuddleWolf: 842
Jack: 1720
JohnNash: 1260
MoveRandomly: 259
SOS: 636
Shotguneer: 777
Sokie: 586
StandStill: 75
SunTzu: 6
SuperCoward: 390
ThePriest: 189
Vortigaunt: 208
Waller: 334
ZombieHater: 61
ZombieRightsActivist: 20

#Run at 03-Aug-2014 15:29:49#
Bee: 90
Cocoon: 516
Coward: 4298
EmoWolfWithAGun: 0
Fox: 1076
GordonFreeman: 581
Gunner: 8
HideyTwitchy: 87
HuddleWolf: 4298
Jack: 4715
JohnNash: 727
MoveRandomly: 102
SOS: 859
Shotguneer: 2471
Sokie: 2471
StandStill: 427
SunTzu: 24
SuperCoward: 159
ThePriest: 359
Vortigaunt: 94
Waller: 398
ZombieHater: 54
ZombieRightsActivist: 21

#Run at 03-Aug-2014 15:36:50#
Bee: 18
Cocoon: 3127
Coward: 3124
EmoWolfWithAGun: 0
Fox: 5094
GordonFreeman: 255
Gunner: 43
HideyTwitchy: 17
HuddleWolf: 1078
Jack: 272
JohnNash: 1270
MoveRandomly: 55
SOS: 723
Shotguneer: 3126
Sokie: 1388
StandStill: 179
SunTzu: 7
SuperCoward: 45
ThePriest: 519
Vortigaunt: 172
Waller: 200
ZombieHater: 45
ZombieRightsActivist: 8

#Run at 03-Aug-2014 15:40:59#
Bee: 78
Cocoon: 1834
Coward: 4521
EmoWolfWithAGun: 0
Fox: 1852
GordonFreeman: 657
Gunner: 7
HideyTwitchy: 2
HuddleWolf: 969
Jack: 895
JohnNash: 1596
MoveRandomly: 277
SOS: 694
Shotguneer: 1397
Sokie: 844
StandStill: 325
SunTzu: 7
SuperCoward: 192
ThePriest: 148
Vortigaunt: 369
Waller: 232
ZombieHater: 16
ZombieRightsActivist: 17

#Run at 03-Aug-2014 15:44:22#
Bee: 23
Cocoon: 2638
Coward: 2269
EmoWolfWithAGun: 0
Fox: 2067
GordonFreeman: 730
Gunner: 21
HideyTwitchy: 60
HuddleWolf: 763
Jack: 1469
JohnNash: 1494
MoveRandomly: 273
SOS: 3181
Shotguneer: 3181
Sokie: 653
StandStill: 450
SunTzu: 19
SuperCoward: 272
ThePriest: 215
Vortigaunt: 299
Waller: 510
ZombieHater: 62
ZombieRightsActivist: 16

#Run at 03-Aug-2014 15:48:03#
Bee: 97
Cocoon: 2009
Coward: 2798
EmoWolfWithAGun: 0
Fox: 1907
GordonFreeman: 958
Gunner: 22
HideyTwitchy: 93
HuddleWolf: 925
Jack: 288
JohnNash: 476
MoveRandomly: 422
SOS: 3723
Shotguneer: 2076
Sokie: 1090
StandStill: 134
SunTzu: 92
SuperCoward: 141
ThePriest: 470
Vortigaunt: 216
Waller: 340
ZombieHater: 32
ZombieRightsActivist: 20

#Run at 03-Aug-2014 16:03:38#
Bee: 121
Cocoon: 501
Coward: 9704
EmoWolfWithAGun: 0
Fox: 3592
GordonFreeman: 588
Gunner: 20
HideyTwitchy: 54
HuddleWolf: 749
Jack: 1245
JohnNash: 1345
MoveRandomly: 451
SOS: 835
Shotguneer: 1548
Sokie: 589
StandStill: 166
SunTzu: 11
SuperCoward: 158
ThePriest: 93
Vortigaunt: 246
Waller: 1350
ZombieHater: 18
ZombieRightsActivist: 11

#Run at 03-Aug-2014 16:10:24#
Bee: 66
Cocoon: 1809
Coward: 3295
EmoWolfWithAGun: 0
Fox: 3214
GordonFreeman: 1182
Gunner: 15
HideyTwitchy: 52
HuddleWolf: 1514
Jack: 101
JohnNash: 745
MoveRandomly: 211
SOS: 862
Shotguneer: 6335
Sokie: 1504
StandStill: 384
SunTzu: 14
SuperCoward: 259
ThePriest: 244
Vortigaunt: 262
Waller: 1356
ZombieHater: 24
ZombieRightsActivist: 20

#Run at 03-Aug-2014 16:28:05#
Bee: 61
Cocoon: 692
Coward: 11141
EmoWolfWithAGun: 0
Fox: 1955
GordonFreeman: 1234
Gunner: 42
HideyTwitchy: 24
HuddleWolf: 1862
Jack: 609
JohnNash: 1579
MoveRandomly: 167
SOS: 958
Shotguneer: 11141
Sokie: 284
StandStill: 422
SunTzu: 66
SuperCoward: 121
ThePriest: 207
Vortigaunt: 128
Waller: 259
ZombieHater: 22
ZombieRightsActivist: 7

#Run at 03-Aug-2014 16:32:10#
Bee: 207
Cocoon: 4414
Coward: 2670
EmoWolfWithAGun: 0
Fox: 978
GordonFreeman: 620
Gunner: 19
HideyTwitchy: 135
HuddleWolf: 962
Jack: 657
JohnNash: 1200
MoveRandomly: 147
SOS: 687
Shotguneer: 2258
Sokie: 2433
StandStill: 249
SunTzu: 49
SuperCoward: 1056
ThePriest: 602
Vortigaunt: 326
Waller: 593
ZombieHater: 31
ZombieRightsActivist: 10

#Run at 03-Aug-2014 16:38:56#
Bee: 265
Cocoon: 2231
Coward: 4228
EmoWolfWithAGun: 0
Fox: 4737
GordonFreeman: 532
Gunner: 9
HideyTwitchy: 75
HuddleWolf: 2375
Jack: 1237
JohnNash: 1249
MoveRandomly: 109
SOS: 860
Shotguneer: 6470
Sokie: 1096
StandStill: 126
SunTzu: 15
SuperCoward: 393
ThePriest: 133
Vortigaunt: 184
Waller: 257
ZombieHater: 32
ZombieRightsActivist: 12

#Run at 03-Aug-2014 16:52:16#
Bee: 67
Cocoon: 1534
Coward: 9324
EmoWolfWithAGun: 0
Fox: 2458
GordonFreeman: 1019
Gunner: 24
HideyTwitchy: 72
HuddleWolf: 601
Jack: 399
JohnNash: 1366
MoveRandomly: 275
SOS: 506
Shotguneer: 1007
Sokie: 475
StandStill: 230
SunTzu: 135
SuperCoward: 361
ThePriest: 61
Vortigaunt: 112
Waller: 4106
ZombieHater: 12
ZombieRightsActivist: 22

#Run at 03-Aug-2014 17:03:04#
Bee: 26
Cocoon: 1159
Coward: 7796
EmoWolfWithAGun: 0
Fox: 3948
GordonFreeman: 878
Gunner: 3
HideyTwitchy: 17
HuddleWolf: 1490
Jack: 513
JohnNash: 1240
MoveRandomly: 487
SOS: 1460
Shotguneer: 1481
Sokie: 832
StandStill: 457
SunTzu: 8
SuperCoward: 480
ThePriest: 527
Vortigaunt: 171
Waller: 3729
ZombieHater: 30
ZombieRightsActivist: 10

1
@Pureferret फ्रीज कोड में एक बड़ी फ़ाइल होती है जिसमें github.com/jamespic/zchin/blob/master/src/main/frege-bindings/… , और एक जावा हेल्पर वर्ग शामिल होता है जो github.com/jamespic पर Frege में कॉल करता है / लाश / बूँद / मास्टर / src / मुख्य / जावा / ज़ोंबी /… । यदि आप रेपो को क्लोन कर सकते हैं (या इसे github.com/jamespic/zchin/archive/master.zip से ज़िप के रूप में डाउनलोड कर सकते हैं ) तो मावेन आपके लिए बिल्ड को हैंडल करेगा।
जेम्स_पिक जूल

1
@Pureferret प्रोजेक्ट को मैन्युअल रूप से सेट करने का प्रयास दर्दनाक होगा । कोई भी व्यक्ति वास्तव में अभी तक उनका उपयोग नहीं करता है, लेकिन आधा दर्जन भाषाओं के लिए संकलक और व्याख्याकार हैं। परावर्तन की अनुमति (वास्तव में, गतिशील भाषाओं में से कुछ इसके बिना काम नहीं कर सकते हैं), इसलिए जब तक यह खेल या आपके प्रतिद्वंद्वियों के साथ छेड़छाड़ करने के लिए उपयोग नहीं किया जाता है। "संचार" के उदाहरण के लिए कायर की लूट पर नज़र रखें।
जेम्स_पिक

1
@sokie यह ठीक लगता है - कुछ प्रविष्टियाँ पहले से ही ऐसा कुछ करती हैं, और मुझे लगा कि जब मैंने चुनौती दी कि कुछ प्रवेशक अपने बॉट्स को कहीं और मिलाना चाहेंगे, या अपने परिवेश के बारे में जानकारी का आदान-प्रदान करेंगे। हम कहेंगे कि खिलाड़ियों को वॉकी टॉकीज़ मिल गए हैं।
जेम्स_पिक

2
@James_pic मैंने Game.java में अपनी स्थानीय प्रति ( pastebin.com/PutPn9ff ) पर इस कोड को जोड़ा ताकि मैं खेल में आगे और पीछे जाने के लिए तीर कुंजियों का उपयोग कर सकूं। सोचा कि यह आपके लिए उपयोगी हो सकता है
Moop

2
थोड़ा निराशा कि विजेता खुद को आत्महत्या करने के बजाय कुछ ज़ोम्बीकरण होने दे।
3

जवाबों:


15

डरपोक

कायरता के नियम।

  1. यदि आप दूर नहीं भागते हैं, तो घबराएं और वह सब कुछ शूट करें जो आप नहीं जानते हैं।
  2. Daud!!!
  3. दौड़ते समय, आप कुछ गोलियों को उठा सकते हैं। नीचे दीप आपको पता है कि आप हमेशा के लिए नहीं चल सकते।
  4. दौड़ते समय अन्य कायरों की तलाश करें। दुख साथी चाहिये। और वे दूसरे आदमी को पहले खा सकते हैं।
package player;

import java.lang.Math.*;
import java.util.Set;
import java.util.HashSet;
import zombie.*;
import static zombie.Constants.*;

public class Coward implements Player {

    private static final Set<PlayerId> killed = new HashSet<>();
    private static final Set<PlayerId> looted = new HashSet<>();

    @Override
    public Action doTurn(PlayerContext context) {

        PlayerId[][] field = context.getPlayField();

        // Panic and shoot
        if (context.getBullets() > 0) {
            int distEnemy = VISION_WIDTH;
            int distZombie = VISION_WIDTH;
            PlayerId targetEnemy = null;
            PlayerId targetZombie = null;
            for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION + SHOOT_RANGE; x++) {
                for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION + SHOOT_RANGE; y++) {
                    PlayerId player = field[x][y];
                    if (player != null && !killed.contains(player)) {
                        int dist = getDistance(x, y);
                        if (player.getName().equals("Zombie")) {
                            if( dist < distZombie ) {
                                distZombie = dist;
                                targetZombie = player;
                            }
                        } else if (isEnemy(player.getName()) && dist <= distEnemy ) {
                            distEnemy = dist;
                            targetEnemy = field[x][y];
                        }
                    }
                }
            }

            if (targetZombie != null && distZombie <= 3) {
                killed.add(targetZombie);
                return new Shoot( targetZombie );
            } else if (targetEnemy != null && distEnemy <= 5 ) {
                killed.add(targetEnemy);
                return new Shoot( targetEnemy );
            }
        }

        // Looted?
        for( int xx = CENTRE_OF_VISION-VISION_RANGE+1; xx <= CENTRE_OF_VISION+VISION_RANGE-1; xx++ ) {
            for( int yy = CENTRE_OF_VISION-VISION_RANGE+1; yy <= CENTRE_OF_VISION+VISION_RANGE-1; yy++ ) {
                PlayerId player = field[xx][yy];
                if( player != null && !player.getName().equals("Zombie") && !player.getName().equals("DeadBody")) {
                    for( int x = -1; x <= 1; x++ ) {
                        for( int y = -1; y <= 1; y++ ) {
                            PlayerId loot = field[xx+x][yy+y];
                            if( loot != null && !looted.contains(loot) && loot.getName().equals("DeadBody")) {
                                looted.add(loot);
                            }
                        }
                    }
                }
            }
        }

        // Run away
        int bestScore = -10000000;
        Move bestMove = Move.randomMove();

        for( int x = -1; x <= 1; x++ ) {
            for( int y = -1; y <= 1; y++ ) {
                PlayerId center = field[CENTRE_OF_VISION+x][CENTRE_OF_VISION+y];
                if( center == null ) {
                    int thisScore = 0;
                    for( int xx = CENTRE_OF_VISION+x-VISION_RANGE+1; xx < CENTRE_OF_VISION+x+VISION_RANGE; xx++ ) {
                        for( int yy = CENTRE_OF_VISION+y-VISION_RANGE+1; yy < CENTRE_OF_VISION+y+VISION_RANGE; yy++ ) {
                            PlayerId player = field[xx][yy];
                            if( player != null) {
                                int dist = getDistance(xx-x,yy-y);

                                if( player.getName().equals("Coward")) { // Prefer lose groups
                                    thisScore += (int)Math.pow( 2, ( 6 - Math.abs( dist - 5 )));
//                                    if( dist >= 3 && dist <= 6 ) {
//                                        thisScore += 32;
//                                    } else if( dist > 3 ) {
//                                        thisScore += 16;
//                                    }
                                } else if( player.getName().equals("DeadBody")) { // Visit dead bodies on the route
                                    if( !looted.contains(player)) {
                                        thisScore += (32+VISION_RANGE-dist)*(VISION_RANGE-dist);
                                    }
                                } else if( player.getName().equals("Zombie")) { // Avoid zombies
                                    if( dist <= 5 ) {
                                        thisScore -= (int)Math.pow( 10, ( 6 - dist ));
                                    }
//                                    if( dist <= 2 ) {
//                                        thisScore -= 10000;
//                                    } else if( dist <= 3 ) {
//                                        thisScore -= 1000;
//                                    } else if( dist <= 4 ) {
//                                        thisScore -= 100;
//                                    }
                                } else if( isEnemy(player.getName())) { // Avoid strangers
                                    thisScore -= (int)Math.pow( 10, ( 9 - dist ));
//                                    if( dist == 7 ) {
//                                        thisScore -= 100;
//                                    } else if( dist <= 6 ) {
//                                        thisScore -= 1000;
//                                    }
                                }
                            }
                        }
                    }
                    if( thisScore > bestScore ) {
                        bestScore = thisScore;
                        bestMove = Move.inDirection( x, y );
                    }
                }
            }
        }

        return bestMove;
    }

    private boolean isEnemy(String name) {
        switch (name) {
            case "Coward":
            case "DeadBody":
            case "GordonFreeman":
            case "EmoWolfWithAGun":
            case "HuddleWolf":
            case "ThePriest":
            case "Shotguneer":
            case "Vortigaunt":
            case "Fox":
            case "Cocoon":
            case "SuperCoward":
            case "SOS":
            case "JohnNash":
            case "MoveRandomly":
                return false;
            default:
                return true;
        }
    }

    private int getDistance(int x, int y) {
        return Math.max(Math.abs(CENTRE_OF_VISION - x), Math.abs(CENTRE_OF_VISION - y));
    }
}

मैं इसे आज़माने के लिए उत्साहित हूं। अब तक की सभी प्रविष्टियों में लड़ाई पर ध्यान केंद्रित किया गया है, लेकिन किसी ने दौड़ने या छिपाने की कोशिश नहीं की।
जेम्स_पिक

ओह, और आपको जो कुछ भी मारा गया है उसका ट्रैक रखने की आवश्यकता नहीं है। यह DeadBodyएक अलग आईडी के साथ दिखाएगा , बजाय जो कुछ भी पहले था।
जेम्स_पिक

1
यह ट्रैक रखने के लिए नहीं है, एक ही चीज़ को एक ही दौर में दो बार शूट नहीं करने के लिए।
थाइलैंड

1
मेड कई बदलाव, सबसे अच्छा एक महाकाव्य तसलीम के साथ चलाने था 2681. पर dl.dropboxusercontent.com/u/13918324/2681.html
Thaylon

1
@ थाइलैंड ने आपके लिए नवीनतम स्रोत कोड तैयार किया है। pastebin.com/4WDb6s8C
HuddleWolf

44

एक बंदूक के साथ भावनाएं भेड़िया

वह वापस आ गया है । उसे लाश से नफरत है। वह अभी भी जावा से नफरत करता है। कॉपीराइट उल्लंघन का इरादा नहीं है।

package player;

import zombie.*;

public class EmoWolfWithAGun implements Player {

    @Override
    public Action doTurn(PlayerContext context) {
        PlayerId myself = context.getId();
        return new Shoot(myself);
    }

}


13

ज़ोंबी अधिकार कार्यकर्ता

ज़ोंबी अधिकारों का आंदोलन तेज़ी से सर्वनाश की भरपाई में लोकप्रिय हो गया। पश्चाताप के बिना हर ज़ोंबी को मारने का विचार उनके लिए बिल्कुल क्रूर है, इसलिए वे अन्य खिलाड़ियों को गोली मारते हैं जो कारण पर विश्वास नहीं करते हैं। संघर्ष को समझते हुए, वे लाश को गले लगा लेंगे यदि दृष्टि में कोई दुश्मन नहीं हैं।

package player;
import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class ZombieRightsActivist implements Player {

@Override
public Action doTurn(PlayerContext context) {
    if (context.getBullets() > 0) {
        for (PlayerId player: context.shootablePlayers()) {
            switch(player.getName()) {
                case "ZombieRightsActivist":
                case "DeadBody":
                case "Zombie":   
                    break;
                default:
                    return new Shoot(player);//Kill the non-believers
            }
        }
    }
    double farthest=0;
    Move move=Move.randomMove();
    for (int x = 0; x < VISION_WIDTH; x++) {//Find a lonely zombie and give it a hug
        for (int y = 0; y < VISION_WIDTH; y++) {
            PlayerId friend = context.getPlayField()[x][y];
            if (friend!= null && (friend.getName().equals("Zombie"))) {
                double distance=sqrt(pow(x-context.getX(),2)+pow(y-context.getY(),2));
                if (distance>farthest){
                    farthest = distance;
                    move = Move.inDirection(x - CENTRE_OF_VISION, y -CENTRE_OF_VISION);
                }
            }
        }
    }
    return move;
}

}

12

हडलवॉल्फ - जावा

नियम 8 : समूहों में यात्रा करें

हडलवुल्फ ज़ोम्बीलैंड के छठे नियम को दिल से लगाता है। यह किसी भी गैर-शत्रुतापूर्ण वस्तु के साथ पीछा करेगा और गड़गड़ाहट करेगा। यदि हडलवुल्फ किसी के साथ हुडदंग करने के लिए नहीं देखता है, तो वह अधिक आबादी वाले क्षेत्रों की तलाश में पूर्वोत्तर की ओर उद्यम करेगा। HuddleWolf भी लाश से नफरत करता है और दृष्टि पर गोली मार देगा।

HuddleWolf ने महसूस किया है कि कायर उनके मूल विचार का बहुत बेहतर कार्यान्वयन है। वह कायर के वर्चस्व के लिए झुकता है और अब सक्रिय रूप से कायरों की कंपनी को अन्य नॉनहॉस्टाइल के लिए पसंद करता है।

package player;

import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class HuddleWolf implements Player {

    @Override
    public Action doTurn(PlayerContext context) {
        if (context.getBullets() > 0) {
            for (PlayerId player: context.shootablePlayers()) {
                if (isEnemy(player.getName())) {
                    return new Shoot(player);
                }
            }
        }
        Move bestDirection = Move.NORTHEAST;
        int bestDistance = Integer.MAX_VALUE;
        bool foundACoward = false;
        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                int distance = max(abs(x - CENTRE_OF_VISION), abs(y - CENTRE_OF_VISION));
                PlayerId playerAtLocation = context.getPlayField()[x][y];
                if (playerAtLocation != null
                        && !(isEnemy(playerAtLocation.getName()))
                        && !(playerAtLocation.equals(context.getId()))
                        && distance < bestDistance
                        && (!foundACoward || playerAtLocation.getName().equals("Coward"))) {
                    if (playerAtLocation.getName().equals("Coward"))
                    {
                        foundACoward = true;
                    }
                    bestDistance = distance;
                    bestDirection = Move.inDirection(x - CENTRE_OF_VISION, y -CENTRE_OF_VISION);
                }
            }
        }
        return bestDirection;
    }

    private boolean isEnemy(String name) {
        switch(name) {
            case "ZombieRightsActivist":
            case "ZombieHater":
            case "HideyTwitchy" :
            case "Gunner":
            case "Zombie" :
                return true;
            default:
                return false;
        }
    }
}

HuddleWolf: अब गनर्स को मारता है
HuddleWolf

तुम भी && !(playerAtLocation.equals(context.getId()))अपने huddling शर्तों में जोड़ना चाह सकते हैं। अभी, यह निकटतम खिलाड़ी की ओर बढ़ता है - निकटतम खिलाड़ी को छोड़कर आप हैं, इसलिए यह स्थिर रहता है।
जेम्स_पिक

क्या आपका मतलब नियम 8 है ....?
प्यूरफेरेट

@Pureferret: आप सही कह रहे हैं। मेरी मूल प्रेरणा Zombieland तोप नहीं थी।
हुडलेवुल्फ

FYI करें ZombieHater को देखें। मुझे नहीं लगता कि वह वास्तव में लाश से नफरत करता है। वह सिर्फ हम सभी को गनर की तरह गोली मारता है। आपको संभवतः उसे अनिवार्य लक्ष्यों की सूची में जोड़ना चाहिए।
किन्नर

11

लोमड़ी

लोमड़ी को लोमड़ी चाहिए।

मेरे कायर के एक अच्छे हिस्से का उपयोग करता है, लेकिन एक अलग रणनीति का पालन करता है। यदि आप (उप) मिशन को स्वीकार करना चुनते हैं, तो लोमड़ी एक लोमड़ी का निर्माण करना पसंद करेगी।

package player;

import java.lang.Math.*;
import java.util.Set;
import java.util.HashSet;
import zombie.*;
import static zombie.Constants.*;

public class Fox implements Player {

    private static int lastround = -1;
    private static final Set<PlayerId> killed = new HashSet<>();
    private static final Set<PlayerId> looted = new HashSet<>();

    @Override
    public Action doTurn(PlayerContext context) {

        PlayerId[][] field = context.getPlayField();

        // Cleanup
        if (context.getGameClock() > lastround) {
            lastround = context.getGameClock();
            killed.clear();
        }

        // Snipe
        if (context.getBullets() > 0) {
            int distEnemy = 1;
            PlayerId targetEnemy = null;
            for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION + SHOOT_RANGE; x++) {
                for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION + SHOOT_RANGE; y++) {
                    PlayerId player = field[x][y];
                    if (player != null && !killed.contains(player)) {
                        int dist = getDistance(x, y);
                        if (!player.getName().equals("Zombie") && isEnemy(player.getName()) && dist >= distEnemy ) {
                            distEnemy = dist;
                            targetEnemy = field[x][y];
                        }
                    }
                }
            }
            if (targetEnemy != null) {
                killed.add(targetEnemy);
                return new Shoot( targetEnemy );
            }
        }

        // Check Foxhole
        int foxhole = 0;
        PlayerId target = null;

        for( int x = -2; x <= 2; x++ ) {
            for( int y = -2; y <= 2; y++ ) {
                PlayerId player = field[CENTRE_OF_VISION+x][CENTRE_OF_VISION+y];
                if (player != null && getDistance(CENTRE_OF_VISION+x,CENTRE_OF_VISION+y) == 2) {
                    if (player.getName().equals("DeadBody") || player.getName().equals("Fox")) {
                        foxhole++;
                    }
                    if( player.getName().equals("Zombie")) {
                        target = player;
                    }
                }
            }
        }

        if (context.getBullets() + foxhole >= 16) {
            if (target!=null) {
                return new Shoot( target );
            } else {
                return Move.STAY;
            }
        }

        // Looted?
        for( int xx = CENTRE_OF_VISION-VISION_RANGE+1; xx <= CENTRE_OF_VISION+VISION_RANGE-1; xx++ ) {
            for( int yy = CENTRE_OF_VISION-VISION_RANGE+1; yy <= CENTRE_OF_VISION+VISION_RANGE-1; yy++ ) {
                PlayerId player = field[xx][yy];
                if( player != null && !player.getName().equals("Zombie") && !player.getName().equals("DeadBody")) {
                    for( int x = -1; x <= 1; x++ ) {
                        for( int y = -1; y <= 1; y++ ) {
                            PlayerId loot = field[xx+x][yy+y];
                            if( loot != null && !looted.contains(loot) && loot.getName().equals("DeadBody")) {
                                looted.add(loot);
                            }
                        }
                    }
                }
            }
        }

        // Collect bullets
        int bestScore = -10000000;
        Move bestMove = Move.randomMove();

        for( int x = -1; x <= 1; x++ ) {
            for( int y = -1; y <= 1; y++ ) {
                PlayerId center = field[CENTRE_OF_VISION+x][CENTRE_OF_VISION+y];
                if( center == null ) {
                    int thisScore = 0;
                    for( int xx = CENTRE_OF_VISION+x-VISION_RANGE+1; xx < CENTRE_OF_VISION+x+VISION_RANGE; xx++ ) {
                        for( int yy = CENTRE_OF_VISION+y-VISION_RANGE+1; yy < CENTRE_OF_VISION+y+VISION_RANGE; yy++ ) {
                            PlayerId player = field[xx][yy];
                            if( player != null) {
                                int dist = getDistance(xx-x,yy-y);

                                if( player.getName().equals("DeadBody")) {
                                    if( !looted.contains(player)) {
                                        thisScore += (32+VISION_RANGE-dist)*(VISION_RANGE-dist);
                                    }
                                } else if( player.getName().equals("Zombie")) {
                                    if( dist <= 5 ) {
                                        thisScore -= (int)Math.pow( 10, ( 6 - dist ));
                                    }
                                }
                            }
                        }
                    }
                    if( thisScore > bestScore ) {
                        bestScore = thisScore;
                        bestMove = Move.inDirection( x, y );
                    }
                }
            }
        }

        return bestMove;
    }

    private boolean isEnemy(String name) {
        switch (name) {
            case "Fox":
            case "Coward":
            case "DeadBody":
            case "GordonFreeman":
            case "EmoWolfWithAGun":
            case "HuddleWolf":
            case "ThePriest":
            case "Shotguneer":
            case "Vortigaunt":
            case "Cocoon":
            case "SuperCoward":
            case "SOS":
            case "JohnNash":
            case "MoveRandomly":
                return false;
            default:
                return true;
        }
    }

    private int getDistance(int x, int y) {
        return Math.max(Math.abs(CENTRE_OF_VISION - x), Math.abs(CENTRE_OF_VISION - y));
    }
}

मुझें यह पसंद है। मुझे चिंता है कि मैं कई प्रविष्टियों (कुछ अधिक आक्रामक प्रविष्टियों को गुर्गे जोड़कर जमीन हासिल करने में सक्षम हो सकता हूं) की अनुमति देकर एक खतरनाक मिसाल कायम करूंगा, लेकिन यह प्रविष्टि स्पष्ट रूप से कायर की मदद नहीं कर सकती है (यदि किसी और ने इसे लिखा था, तो) उन्होंने शायद कमोबेश यही काम किया होगा), इसलिए मैं इसकी अनुमति दूंगा। मुझे कल इसका परीक्षण करने का मौका मिलना चाहिए।
17_ पर जेम्स_पिक

जोड़ा बेहतर स्कोरिंग (संबंधों के कारण अभी भी नहीं खड़ा है) और लूट के रूप में अधिक डेडबॉडी को चिह्नित करता है। बेहतर खतरे की गणना करने की कोशिश करना पसंद करेंगे, लेकिन परीक्षण प्रक्रिया को कायर के साथ कभी-कभी 15000 राउंड तक चलने में बहुत समय लगता है। यह शायद मुख्य रूप से बड़े खेल मैदान के कारण होता है और इस प्रकार एक ज़ोंबी द्वारा कम होने की संभावना कम हो जाती है। सबसे अच्छी रणनीति यह लगती है: 1000 से अधिक खिलाड़ियों को जितना संभव हो सके घुमाएं, आगे बढ़ना बंद करें और फिर भाग्य का फैसला करें।
थाइलॉन

10

वालर - जावा

वालर दीवारों से प्यार करता है, और उन्हें लाश से छिपाने के लिए बाहर चाहता है। आदर्श रूप से, वालर को एक दीवार में घेरना पसंद होगा और सर्वनाश की प्रतीक्षा करेगा।

आदर्श दीवार

आदर्श दीवार वह है जहाँ दीवारों से दीवार पूरी की जाती है:

   DDD 
   DWD 
   DDD

के रूप में मरने का एकमात्र तरीका शॉट या एक ज़ोंबी spawns के नीचे या आप पड़ोसी है। यह उनसे बचने के लिए सबसे अच्छा संभव है।

आदर्श दीवार से आना मुश्किल है, लेकिन वालर को सबसे अच्छा संभव स्थान मिल जाएगा और लाश या अन्य खिलाड़ियों की प्रतीक्षा करें ताकि वह अपनी दीवार की शूटिंग और विस्तार कर सकें।


एल्गोरिथ्म अपेक्षाकृत सरल है

  1. क्या काटने के बारे में एक ज़ोंबी है? उन्हें गोली मार दो।
  2. देखने के क्षेत्र में सबसे अच्छा दीवार स्थान (0 - 8 रन बनाए) खोजें
  3. उस स्थान पर सबसे छोटा रास्ता खोजें और उसे चलाएं!
  4. दीवार बढ़ाने का प्रयास करें
  5. रुको...

यह प्रगति में एक काम है, जो कुछ भी मैंने अपने लिए उपयोग करने के लिए लिखा है उसे लेने के लिए स्वतंत्र महसूस करें। मैंने दीवारों और अन्य खिलाड़ियों को ध्यान में रखते हुए वांछित स्थान पर सबसे अच्छा रास्ता खोजने के लिए एक सरल ए * एल्गोरिथम लिखा । यह प्रत्येक दौर में पुनर्गठित हो जाता है क्योंकि दीवारें उनके बीच बदल गई होंगी।


बदलाव का:

  • दीवारों को खोजने / निर्माण करने से पहले पहले कुछ मोड़ के लिए बाहर इंतजार करके और आक्रामक खिलाड़ियों से बचने के लिए जल्दी खेल प्रदर्शन में सुधार करने की कोशिश की।

  • दूरी और स्थिति स्कोर के मामले में सबसे अच्छा मार्ग लेने के लिए पथ खोजने के लिए वजन जोड़ा गया। अब और अधिक बार लूट करेंगे और उम्मीद है कि गोलियों से नहीं भागेंगे। आक्रामक खिलाड़ियों से दूर भागते हुए बेहतर शुरुआती खेल।

  • एक व्यस्त बिंदु पर समाप्त होने वाले पथ के साथ फिक्स्ड मुद्दे

  • आगे कोड साफ किया। केवल पड़ोसी दीवारों की तुलना में एक स्थिति स्कोर करने के लिए और अधिक दीवारें जोड़ी गईं। विस्तारित किया गया कि वालर अपनी दीवार को कितना आगे बढ़ाएगा।

  • साफ कोड थोड़ा ऊपर। एक ही मोड़ के दौरान एक ही खिलाड़ी की शूटिंग से बचने के लिए शूटिंग रजिस्ट्री लागू की गई (थाइलोन से प्रेरित)

  • निकटतम लाश और वर्तमान Walelr के बीच पथ खोज। वालर केवल एक ज़ोंबी को गोली मार देगा यदि यह निश्चित संख्या में चालों में उस तक पहुंच सकता है। यह उम्मीद है कि कुछ गोलियां बच जाएंगी जब उनकी दीवार ज़ोंबी के रास्ते को अवरुद्ध कर देगी।


मुद्दे

  • वालर एक अच्छी स्थिति में हो सकता है, लेकिन एक बेहतर दीवार स्थान देखता है। वे उस नए स्थान तक पहुंचने के लिए ज़ोंबी-संक्रमित भूमि के माध्यम से नासमझी करेंगे। (मुझे इसे हतोत्साहित करने की आवश्यकता है)

  • शुरुआती खेल वालर के लिए कठिन है, कोई अच्छा किलेबंदी पास नहीं है और बहुत सारे आक्रामक खिलाड़ी हैं। (मैं जल्दी खेल प्रदर्शन में सुधार करने की जरूरत है)

  • समान स्थानों में वालर्स के बीच कोई संचार नहीं। आवश्यकता है कि वे एक साथ काम करने के लिए सबसे अच्छी दीवार का निर्माण संभव है।


यहाँ कोड है, मैं जावा प्रोग्रामर नहीं हूँ (C #) इसलिए मेरी जावा त्रुटियों को क्षमा करें।

package player;

import java.lang.Math.*;
import java.util.Set;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;
import java.util.Collections;
import java.util.Comparator;
import zombie.*;
import static zombie.Constants.*;

public class Waller implements Player {

    private static final int MaximumDistanceToShootZombie = 2;
    private static final int PointsPerWall = 3;
    private static final int PointsPerLoot = 3;
    private static final int PointsPerZombie = -500;
    private static final int PointsPerAggressor = -500;  

    private static final Set<PlayerId> shooting = new HashSet<PlayerId>();
    private static final Set<PlayerId> dontLoot = new HashSet<PlayerId>();
    private static final Set<Point> zombieLocations = new HashSet<Point>();
    private Point CurrentLocation = new Point(CENTRE_OF_VISION, CENTRE_OF_VISION);

    private static int _lastGameTurn = -1;

    // DEBUG
    private static boolean _DEBUG = true;
    private static int agressiveKills;
    private static int zombieKills;
    private static int wallsBuilt;
    ////////

    private static class Point{
        public int X;
        public int Y;
        public PlayerId Player;
        public int Distance;

        public Point(int x, int y) {
            X = x;
            Y = y;
        }

        public Point(int x, int y, PlayerId player) {
            X = x;
            Y = y;
            Player = player;
        }

        public boolean SameLocation(Point otherPoint) {
            return X == otherPoint.X && Y == otherPoint.Y;
        }

        public List<Point> getAdjacentPoints(PlayerId[][] field, int distance, boolean includeSelf) {
            List<Point> points = new ArrayList<Point>();
            for(int x = X - distance; x <= X + distance; x++) {
                for(int y = Y - distance; y <= Y + distance; y++) { 
                    if(!includeSelf && x == X && y == Y)
                        continue;
                    Point pointToAdd = new Point(x, y);                 
                    if(pointToAdd.isValid()) {
                        pointToAdd.Player = field[x][y];
                        points.add(pointToAdd);
                    }
                }
            }                   
            return points;
        }

        public int GetDistance(Point point) {
            return Math.max(Math.abs(X - point.X), Math.abs(Y - point.Y));
        }

        private boolean isValid() { 
            return X >= 0 && X < VISION_WIDTH && Y >= 0 && Y < VISION_WIDTH;
        }

        @Override
        public int hashCode() {
            return (X*100) + Y;  
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Point))
                return false;
            if (obj == this)
                return true;

            return SameLocation((Point) obj);       
        }

        @Override
        public String toString(){
            return "("+X+","+Y+")";
        }           
    }

    @Override
    public Action doTurn(PlayerContext context) {   
        int gameTurn = context.getGameClock();  

        if(gameTurn != _lastGameTurn){
            _lastGameTurn = gameTurn;               
        }

        PlayerId[][] field = context.getPlayField();         
        int bullets = context.getBullets();

        // Mark all adjacent dead players as already been looted
        for(Point point : getSurrounding(field, CENTRE_OF_VISION, CENTRE_OF_VISION, 1)){
            if(point.Player.getName().equals("DeadBody")) 
                dontLoot.add(point.Player);  
        }

        int x = context.getX();
        int y = context.getY();
        int boardSize = context.getBoardSize();
        List<Point> newZombies = new ArrayList<Point>();
        for(Point point : getSurrounding(field, CENTRE_OF_VISION, CENTRE_OF_VISION, VISION_RANGE)){     
            Point absolutePoint = GetNewTorusPoint(x + point.X - CENTRE_OF_VISION , y + point.Y - CENTRE_OF_VISION, boardSize);         
            if(point.Player.getName().equals("DeadBody") && zombieLocations.contains(absolutePoint)) 
                dontLoot.add(point.Player);  // new zombie kill
            if(isZombie(point.Player))
                newZombies.add(absolutePoint);
        }
        zombieLocations.clear();
        zombieLocations.addAll(newZombies);

        Action action;  

        // 1) Handle immediate threats to life, have to be dealt before anything else
        action = AssessThreats(field, bullets);
        if(action != null) return action;

        //2) Early turn avoidance
        if(gameTurn < 5) {
            action = EarlyTurn(field, bullets, context);
            if(action != null) return action;
        }

        int currentWallCount = countNumberOfSurroundingWalls(field, CENTRE_OF_VISION, CENTRE_OF_VISION);

        switch(currentWallCount) {  
            case 8:     
                action = ShootAgressivePlayers(field, bullets);
                if(action != null) return action; 
                return Move.STAY; // no more moving                 
            case 7:     
                action = ExpandWall(field, bullets, 1);
                if(action != null) return action;
                action = ShootAgressivePlayers(field, bullets);
                if(action != null) return action;                   
            case 6: 
            case 5:              
            case 4: 
                // action = ExpandWall(field, bullets, 2);
                // if(action != null) return action; 
                // break;
            case 2: 
            case 1: 
            default:                                    
                break;
        }                       

        // 2) Score each possible square and find the best possible location(s)
        Set<Point> optimalLocations = scoreSquares(field);  

        action = findShortestPath(field, CurrentLocation, optimalLocations);
        if(action != null) return action;

        action = ShootAgressivePlayers(field, bullets);
        if(action != null) return action;   

        action = ExpandWall(field, bullets, 1);
        if(action != null) return action;    

        // Stay still if nothing better to do
        return Move.STAY;
    }

    private Action EarlyTurn(PlayerId[][] field, int bullets, PlayerContext context) {
        Point bestPoint = CurrentLocation;
        double bestScore = 1000000;

        for(Point futurePoint : CurrentLocation.getAdjacentPoints(field, 1, true)) {            
            double score = 0;
            for(Point adjacentPoint : futurePoint.getAdjacentPoints(field, VISION_RANGE, false)) {
                if(isAgressive(adjacentPoint.Player)){
                    int dist = futurePoint.GetDistance(adjacentPoint);          
                    if(dist > 6){
                        score += 1;             
                    } else {
                        score += 10000;
                    }
                } else if(isZombie(adjacentPoint.Player)) {
                    int dist = futurePoint.GetDistance(adjacentPoint);      
                    if (dist <= 3)
                        score += 10000;
                } else if(isWall(adjacentPoint.Player)) {
                    score -= 2;
                }
            }   
            if(score < bestScore) {
                bestScore = score;
                bestPoint = futurePoint;
            }
        }                           

        //if(_DEBUG) System.out.println("["+_lastGameTurn+"] Best Score: "+bestScore +" point: "+context.getX()+","+context.getY());

        if(bestPoint == CurrentLocation) {
            Action action = ShootAgressivePlayers(field, bullets);
            if(action != null) return action;   
            return Move.STAY;
        }

        if(bestScore >= 1000) {
            Action action = ShootAgressivePlayers(field, bullets);
            if(action != null) return action;   
        }

        return Move.inDirection(bestPoint.X - CurrentLocation.X, bestPoint.Y - CurrentLocation.Y);      
    }

    private Action ShootAgressivePlayers(PlayerId[][] field, int bullets) {
        if(bullets > 0) {       
            for(Point point : getSurrounding(field, CENTRE_OF_VISION, CENTRE_OF_VISION, SHOOT_RANGE)) {
                PlayerId player = point.Player;
                if(isAgressive(player) && shouldShoot(player)) {
                    if(_DEBUG) System.out.println("["+_lastGameTurn+"] Killing Aggressive: "+(++agressiveKills));       
                    return new Shoot(player);
                }           
            }   
        }
        return null;
    }

    private Action ExpandWall(PlayerId[][] field, int bullets, int distance) {
        if(bullets > 0) {
            for(Point point : getSurrounding(field, CENTRE_OF_VISION, CENTRE_OF_VISION, distance)) {
                PlayerId player = point.Player;
                if(!isWall(player) && isEnemy(player) && !isZombie(player) && shouldShoot(player)) {
                    if(_DEBUG) System.out.println("["+_lastGameTurn+"] Expanding Wall: "+(++wallsBuilt)+" Dist: "+CurrentLocation.GetDistance(point));          
                    return new Shoot(player);
                }           
            }
        }
        return null;
    }

    private boolean shouldShoot(PlayerId player) {
        boolean result = shooting.add(player);
        if(result && isZombie(player)){
            dontLoot.add(player);           
        }       
        return result;      
    }

    private boolean canShoot(PlayerId player) {
        return !shooting.contains(player);      
    }

    private Action AssessThreats(PlayerId[][] field, int bullets){ 
        // Find the most threatening zombie     
        List<Point> bestZombies = new ArrayList<Point>();
        int smallestDistance = MaximumDistanceToShootZombie+1;      
        for(Point point : getSurrounding(field, CENTRE_OF_VISION, CENTRE_OF_VISION, MaximumDistanceToShootZombie)) {
            PlayerId zombie = point.Player;
            if(isZombie(zombie)) {              
                LinkedList<Point> path = findShortestPath_astar(field, CurrentLocation, point, false, false);               
                if(path.isEmpty()) 
                    continue;  
                if(path.size() <= smallestDistance && canShoot(zombie)) {
                    if(path.size() < smallestDistance) {
                        smallestDistance = path.size();
                        bestZombies.clear();
                    }
                    bestZombies.add(point);                                                                                            
                }    
            }
        }

        // No zombies to worry about
        if(bestZombies.isEmpty())
            return null;

        if(bestZombies.size() > 1) {
            if(_DEBUG) System.out.println("["+_lastGameTurn+"] Multiple Zombies in striking range, wait them out?");        
            return MoveToBestSpot(field);   
        }

        Point zombie = bestZombies.get(0);

        // Do we have ammo?
        if(bullets > 0 && shouldShoot(zombie.Player)) { 
            if(_DEBUG) System.out.println("["+_lastGameTurn+"] Shooting Zombie: "+(++zombieKills));             
            return new Shoot(zombie.Player);
        } 

        if(_DEBUG) System.out.println("["+_lastGameTurn+"] No Bullets to Shoot Zombie! Should flee");           
        return MoveInDirection(field, CENTRE_OF_VISION - zombie.X, CENTRE_OF_VISION - zombie.Y);    
    }

    private Action MoveToBestSpot(PlayerId[][] field) { 
        int leastZombies = 100000;
        Point bestPoint = CurrentLocation;
        for(Point point : CurrentLocation.getAdjacentPoints(field, 1, false)) {
            if(point.Player == null) {
                int zombies = countNumberOfSurroundingZombies(field, point.X, point.Y);
                if(zombies < leastZombies) {
                    leastZombies = zombies;
                    bestPoint = point;
                }
            }
        }
        return Move.inDirection(bestPoint.X - CurrentLocation.X, bestPoint.Y - CurrentLocation.Y);
    }

    private Action MoveInDirection(PlayerId[][] field, int x, int y) {
        x = (int)Math.signum(x);
        y = (int)Math.signum(y);

        if(y == 0){
            if(field[CENTRE_OF_VISION+x][CENTRE_OF_VISION] != null)
                return Move.inDirection(x,0);
            if(field[CENTRE_OF_VISION+x][CENTRE_OF_VISION-1] != null)
                return Move.inDirection(x,-1);
            if(field[CENTRE_OF_VISION+x][CENTRE_OF_VISION+1] != null)
                return Move.inDirection(x,1);   
        } else if(x == 0){
            if(field[CENTRE_OF_VISION][CENTRE_OF_VISION+y] != null)
                return Move.inDirection(0,y);
            if(field[CENTRE_OF_VISION-1][CENTRE_OF_VISION+y] != null)
                return Move.inDirection(-1,y);
            if(field[CENTRE_OF_VISION+1][CENTRE_OF_VISION+y] != null)
                return Move.inDirection(1,y);   
        } else {        
            if(field[CENTRE_OF_VISION+x][CENTRE_OF_VISION+y] != null)
                return Move.inDirection(x,y);
            if(field[CENTRE_OF_VISION+x][CENTRE_OF_VISION] != null)
                return Move.inDirection(x,0);
            if(field[CENTRE_OF_VISION][CENTRE_OF_VISION+y] != null)
                return Move.inDirection(0,y);   
        }

        return Move.inDirection(0,0);   
    }

    // Implementation of the A* path finding algorithm
    private LinkedList<Point> findShortestPath_astar(PlayerId[][] field, Point startingPoint, Point finalPoint, boolean includeWeights, boolean considerPlayersAsWalls) {   
        LinkedList<Point> foundPath = new LinkedList<Point>();
        Set<Point> openSet = new HashSet<Point>();
        Set<Point> closedSet = new HashSet<Point>();
        Hashtable<Point, Integer> gScores = new Hashtable<Point, Integer>();
        Hashtable<Point, Point> cameFrom = new Hashtable<Point, Point>();

        gScores.put(startingPoint, 0);
        openSet.add(startingPoint);
        Point currentPoint = startingPoint;

        while(!openSet.isEmpty()) {

            // Find minimum F score
            int minF = 10000000;
            for(Point point : openSet) {
                int g = gScores.get(point);
                int h = point.GetDistance(finalPoint); // Assumes nothing in the way                
                int f = g + h;
                if(f < minF) {
                    minF = f;               
                    currentPoint = point;
                }           
            }

            // Found the final point
            if(currentPoint.SameLocation(finalPoint)) {                 
                Point curr = finalPoint;
                while(!curr.SameLocation(startingPoint)) {
                    foundPath.addFirst(curr);
                    curr = cameFrom.get(curr);
                }
                return foundPath;
            }

            openSet.remove(currentPoint);
            closedSet.add(currentPoint);            

            // Add neighbouring squares
            for(Point pointToAdd : currentPoint.getAdjacentPoints(field, 1, false)){                            
                if(closedSet.contains(pointToAdd) || isWall(pointToAdd.Player) || (considerPlayersAsWalls && pointToAdd.Player != null && !pointToAdd.SameLocation(finalPoint) )) 
                    continue;

                int gScore = gScores.get(currentPoint) + 1; // distance should always be one (may change depending on environment)  
                // if(includeWeights){
                    // gScore += (int)-getScore(field,pointToAdd.X,pointToAdd.Y);
                // }   

                boolean distIsBetter = false;   

                if(!openSet.contains(pointToAdd)) {
                    openSet.add(pointToAdd);
                    distIsBetter = true;
                } else if(gScore < gScores.get(pointToAdd)){                    
                    distIsBetter = true;
                }
                if(distIsBetter) {
                    gScores.put(pointToAdd, gScore);
                    cameFrom.put(pointToAdd, currentPoint);                     
                }
            }  
        }

        return foundPath;   
    }

    private Action findShortestPath(PlayerId[][] field, Point startingPoint, Set<Point> finalPoints) {    
        if(finalPoints.isEmpty())
            return null;
        int smallestPath = 10000;       
        Point pointToMoveTo = startingPoint;  

        for(Point finalPoint : finalPoints) {  
            if(finalPoint == startingPoint)
                return null;
            LinkedList<Point> path = findShortestPath_astar(field, startingPoint, finalPoint, true, true);

            // No path between the two points
            if(path.isEmpty()){
                continue;
            }

            // Check if this is the smallest path
            if(path.size() < smallestPath) {                
                smallestPath = path.size();             
                pointToMoveTo = path.getFirst();                
            }           
        }       

        if(pointToMoveTo == startingPoint)
            return null;

        double score = getScore(field, pointToMoveTo.X, pointToMoveTo.Y);
        if(score < -200) {
            if(_DEBUG) System.out.println("["+_lastGameTurn+"] Best Path leads to a bad spot: "+score);     
            return null;
        }

        return Move.inDirection(pointToMoveTo.X - startingPoint.X, pointToMoveTo.Y - startingPoint.Y);          
    }

    private Set<Point> scoreSquares(PlayerId[][] field) {
        double bestScore = getScore(field, CENTRE_OF_VISION, CENTRE_OF_VISION) + 1; // plus one to break ties, and would rather stay
        Set<Point> bestLocations = new HashSet<Point>();
        if(bestScore >= 0) {
            bestLocations.add(CurrentLocation);         
        } else {
            bestScore = 0;
        }

        for(int x = 0; x < VISION_WIDTH; x++){
            for(int y = 0; y < VISION_WIDTH; y++){   
                if(x == CENTRE_OF_VISION && y == CENTRE_OF_VISION) continue;
                if(field[x][y] == null) {                                 
                    double score = getScore(field, x, y);           
                    if(score >= bestScore){
                        if(score > bestScore) {
                            bestLocations.clear();
                            bestScore = score;   
                        }
                        bestLocations.add(new Point(x, y));                      
                    }
                }
            }
        }       
        return bestLocations;
    }

    private double getScore(PlayerId[][] field, int x, int y) {
        int walls = countNumberOfSurroundingWalls(field, x, y); 
        double score = Math.pow(PointsPerWall, walls);      
        int aggressors = countNumberOfSurroundingAggressions(field, x, y);
        score += aggressors * PointsPerAggressor;   
        int zombies = countNumberOfSurroundingZombies(field, x, y);
        score += zombies * PointsPerZombie;
        int loots = countNumberOfSurroundingLoots(field, x, y);
        score += Math.pow(PointsPerLoot, loots);        
        return score;       
    }

    private int countNumberOfSurroundingZombies(PlayerId[][] field, int x, int y) {     
        int zombies = 0;
        Point currentPoint = new Point(x,y);
        for(Point point : getSurrounding(field, x, y, MaximumDistanceToShootZombie+1)){         
            if(isZombie(point.Player)){
                LinkedList<Point> path = findShortestPath_astar(field, currentPoint, point, false, false);
                if(path.isEmpty()) 
                    continue; 
                if(path.size() < MaximumDistanceToShootZombie+1)
                    zombies++;                  
            }            
        }
        return zombies;           
    }

    private int countNumberOfSurroundingLoots(PlayerId[][] field, int x, int y) {     
        int loots = 0;  
        for(Point point : getSurrounding(field, x, y, 1)){
            PlayerId player = point.Player;
            if(isWall(player) && !dontLoot.contains(player)){   
                loots++;                    
            }            
        }
        return loots;   
    }

    private int countNumberOfSurroundingAggressions(PlayerId[][] field, int x, int y) {     
        int aggressors = 0; 
        for(Point point : getSurrounding(field, x, y, SHOOT_RANGE+1)){
            if(isAgressive(point.Player)){
                aggressors++;                   
            }            
        }
        return aggressors;           
    }

    private int countNumberOfSurroundingWalls(PlayerId[][] field, int x, int y) {
        int walls = 0;      
        for(Point point : getSurrounding(field, x, y, 1)){
            if(isWall(point.Player)){
                walls++;                    
            }            
        }
        return walls;
    }

    private static boolean isZombie(PlayerId player) {
        return player != null && player.getName().equals("Zombie");
    }

    private static boolean isWall(PlayerId player) {
        return player != null && player.getName().equals("DeadBody");       
    }

    private static boolean isEnemy(PlayerId player) {
        if(player == null)
            return false;
        switch (player.getName()) {  
            case "Waller":
            case "DeadBody": 
            case "EmoWolfWithAGun":
                return false;
            default:
                return true;
        }
    }

    private static boolean isAgressive(PlayerId player) {
        if(player == null)
            return false;
        switch (player.getName()) {  
            case "Waller":
            case "DeadBody":   
            case "EmoWolfWithAGun":
            case "GordonFreeman":
            case "Vortigaunt": 
            case "StandStill":
            case "MoveRandomly":
            case "Zombie":
                return false;
            default:
                return true;
        }
    }

    // Helper Functions 

    private List<Point> getSurrounding(PlayerId[][] field, int x, int y, int maxDistance) {      
        final Point currentPoint = new Point(x,y);

        List<Point> players = new ArrayList<Point>();
        int minX = coercePoint(x - maxDistance);
        int maxX = coercePoint(x + maxDistance);
        int minY = coercePoint(y - maxDistance);
        int maxY = coercePoint(y + maxDistance);
        for(int i = minX; i <= maxX; i++){
            for(int j = minY; j <= maxY; j++) {
                if(i == x && j == y) continue;
                if(field[i][j] != null) {                
                    Point point = new Point(i,j,field[i][j]);
                    point.Distance = currentPoint.GetDistance(point);
                    players.add(point);
                }
            }
        }           

        Collections.sort(players, new Comparator<Point>() {
            public int compare(Point p1, Point p2) {
                return Integer.compare(p1.Distance, p2.Distance);          
            }});        

        return players;
    }

    private static int coercePoint(int value) {
        if(value < 0)
            return 0;
        if(value >= VISION_WIDTH)
            return VISION_WIDTH-1;
        return value;
    }

    public static Point GetNewTorusPoint(int x, int y, int boardSize) {
        if(x >= boardSize)
            x = boardSize - x;
        if(y >= boardSize)
            y = boardSize - y;
        return new Point(x,y);
    }

    private static int getDistance(int x1, int y1, int x2, int y2) {
        return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
    }
}

ऊह, यह अच्छा है। मैं उम्मीद कर रहा था कि कोई व्यक्ति एल्गोरिथ्म खोजने के लिए एक वास्तविक पथ के साथ कुछ करेगा - मैं दिज्क्स्ट्रा के साथ थोड़ा खेल रहा हूं, लेकिन ऐसा लगता है कि यह मेरे काम को अप्रचलित कर सकता है।
जेम्स_पिक

@ जेम्स_पिक धन्यवाद, मैं आज रात उनके साथ खेल रहा था। जब आप रास्ता खोजते हैं तो बहुत सारी दिलचस्प बातें। मेरे प्रारंभिक परीक्षणों ने उन्हें कायर और शॉटग्यूनर के पीछे तीसरे स्थान पर रखा।
Moop

ऐसा नहीं है कि कोई भी इसके बारे में कुछ भी कर सकता है, लेकिन फ़िजी, लाश न केवल खाली खेतों या खिलाड़ियों पर बल्कि डेडबॉडी के अस्वस्थ होने के कारण हो सकता है।
थायोन

@ थाइलोन ने देखा कि ouput नक्शे को देखते समय। कुछ भी मैं किसी भी रास्ते के लिए तैयार नहीं कर सकता, लेकिन मेरे लिए बाहर देखने के लिए धन्यवाद।
Moop

यह एक दीवार के रूप में स्टैंडस्टिल के इलाज के लिए एक गलती हो सकती है। बेशक, यह नहीं चलता है, लेकिन यह एक ज़ोंबी के खिलाफ रक्षा नहीं है
जेम्स_पिक जूल 30'14

8

गॉर्डन फ्रीमैन

गॉर्डन फ्रीमैन को लाश से नफरत है, इसलिए वह कभी भी खुद को नहीं मारेंगे, लेकिन अधिक लाश को गोली मारने के लिए अधिक बारूद को खुरचने के साथ उनके पास कोई योग्यता नहीं है।

package player;

import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class GordonFreeman implements Player {
    @Override
    public Action doTurn(PlayerContext context){
        int ammo = context.getBullets();
        // if I have bullets, shoot some zombies
        if(ammo > 0){
            for(PlayerId player: context.shootablePlayers()){
                switch(player.getName()){
                    case "Zombie":
                       return new Shoot(player);
                    default:
                       break;
                }
            }
        }
        // if no bullets, find a dead body and scavenge
        Move bestDirection = Move.STAY;
        int bestDistance = Integer.MAX_VALUE;
        for(int y = 1; y < VISION_WIDTH - 1; y++) {
            for(int x = 1; x < VISION_WIDTH - 1; x++) {

                PlayerId playerAtLocation = context.getPlayField()[x][y];
                // find a dead body
                if((playerAtLocation != null) && "DeadBody".equals(playerAtLocation.getName())){
                    // check adjacent squares for an empty square
                    for(int yy=-1; yy <= +1; yy++){
                        for(int xx=-1; xx <= +1; xx++){
                            PlayerId playerNearby = context.getPlayField()[x + xx][y + yy];
                            if(playerNearby == null){
                                int distance = max(abs(xx + x - CENTRE_OF_VISION), abs(yy + y - CENTRE_OF_VISION));
                                if(distance < bestDistance){
                                    bestDistance = distance;
                                    bestDirection = Move.inDirection(xx + x - CENTRE_OF_VISION, yy + y - CENTRE_OF_VISION);
                                }
                            }
                        }
                    }
                }
            }
        }
        return bestDirection;
    }
}

मुझे आशा है कि आपको कोई आपत्ति नहीं है, लेकिन मैंने इसे संकलित करने के लिए अपने कोड में कुछ मामूली संपादन किए हैं, और कुछ अशक्त सूचक या सरणी इंडेक्स बग्स को ठीक किया है, जो इसे रन-टाइम में त्रुटि कर रहे थे। मैंने तर्क नहीं बदला है।
जेम्स_पिक

@ जेम्स_पिक: मैं सुधारों की सराहना करता हूं, मैं कम से कम जावा प्रोग्रामर नहीं हूं, हालांकि मुझे लगता है कि मुझे इन कोठ चुनौतियों के लिए काफी अच्छा लगता है: डी।
काइल कानोस

आप पिछले मैच के रिप्ले में jamespic.github.io/zili/2014-07-21/0.html पर नज़र डाल सकते हैं । ऐसा लगता है कि डॉ। फ्रीमैन हमेशा उत्तर-पश्चिम में चलते हैं, जो उनके असंगत प्रदर्शन की व्याख्या कर सकते हैं।
जेम्स_पिक

@ जेम्स_पिक: फ्रीमैन कौन सा है? दो जी हैं (एक नीला, दूसरा पीला)। अगर मेरा ब्लू जी है, तो ऐसा लगता है कि वह यादृच्छिक रूप से चलता है, न कि केवल एनडब्ल्यू। इसके अलावा, क्या एक मृत ज़ोंबी और मृत मानव के बीच बताने का कोई तरीका है?
काइल कानोस

1
धन्यवाद :) मुझे लगता है कि जब मैं कर सकता हूं तो कोड का पुन: उपयोग करना पसंद करता हूं, लेकिन जब यह मेरा नहीं है तो मैं स्वीकार करना पसंद करता हूं।
सोकी 13:29

7

पुजारी

यदि आपको विश्वास है, तो आपको दौड़ने की जरूरत नहीं है और न ही शॉट लगाने की।

package player;

import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class ThePriest implements Player {

    @Override
    public Action doTurn(PlayerContext context) {
        return Move.NORTH;
    }
}

4
HuddleWolf.... मैं देख रहा हूँ कि आपने वहाँ क्या किया?)
काइल कानोस

मुझे डर है कि आपको अपनी कक्षा को इसके अलावा कुछ और नाम देने की आवश्यकता होगी HuddleWolf, क्योंकि यह नाम पहले से ही लिया गया है
James_pic

6

ZombieHater

यह सबमिशन लाश से नफरत करता है! यह निकटतम ज़ोंबी को शूट करने की कोशिश करता है जबकि इसमें गोलियां होती हैं, फिर अधिक लाश को मारने के लिए अधिक गोलियां एकत्र करता है।

संपादित करें: ZombieHater अब अन्य लोगों को और अधिक गोलियां मारने में संकोच नहीं करता है। यह बाधाओं का भी पता लगाता है और उनके चारों ओर जाने की कोशिश करता है।

package player;

import java.awt.Point;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import zombie.*;
import static zombie.Constants.*;

public class ZombieHater implements Player {
    private static final Set<PlayerId> emptyDeadBodies = new HashSet<>();
    private static final Map<PlayerId, Point> lastPos = new HashMap<>();

    @Override
    public Action doTurn(PlayerContext context) {
        PlayerId[][] field = context.getPlayField();
        Point myPos = new Point(context.getX(), context.getY());
        PlayerId myId = context.getId();

        // update dead bodies with the new empty ones
        addEmptyBodies(field);

        // shoot nearest zombie if possible
        if (context.getBullets() > 0) {
            PlayerId nearestZombie = getNearestEnemy(field);
            if (nearestZombie != null) {
                lastPos.remove(myId);
                return new Shoot(nearestZombie);
            }
        }

        // stuck, mostly because of dead body
        if (lastPos.containsKey(myId) && lastPos.get(myId).equals(myPos)) {
            return Move.randomMove();
        }

        // walk towards dead bodies
        Point nearestDeadBody = getNearestDeadBody(field);
        if (nearestDeadBody != null) {
            Move move = Move.inDirection(nearestDeadBody.x - CENTRE_OF_VISION, nearestDeadBody.y - CENTRE_OF_VISION);
            lastPos.put(myId, myPos);
            return move;
        }

        lastPos.remove(myId);
        return Move.randomMove();
    }

    // add surrounding dead bodies to empty bodies
    private void addEmptyBodies(PlayerId[][] field) {
        for (Move move : Move.values()) {
            PlayerId player = field[CENTRE_OF_VISION + move.x][CENTRE_OF_VISION + move.y];
            if (player != null && "DeadBody".equals(player.getName())) {
                emptyDeadBodies.add(player);
            }
        }
    }

    // distance from centre, for example 5 if x=7 and y=3
    private int distanceFromCentre(int x, int y) {
        int dx = Math.abs(CENTRE_OF_VISION - x);
        int dy = Math.abs(CENTRE_OF_VISION - y);
        return Math.max(dx, dy);
    }

    // return nearest enemy or null if none exists
    private PlayerId getNearestEnemy(PlayerId[][] field) {
        int minOffset = Integer.MAX_VALUE;
        PlayerId nearestEnemy = null;
        for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION + SHOOT_RANGE; x++) {
            for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION + SHOOT_RANGE; y++) {
                int offset = distanceFromCentre(x, y);
                PlayerId player = field[x][y];
                if (player != null && isEnemy(player.getName()) && offset < minOffset) {
                    minOffset = offset;
                    nearestEnemy = field[x][y];
                }
            }
        }
        return nearestEnemy;
    }

   // return nearest dead body or null if none exists
    private Point getNearestDeadBody(PlayerId[][] field) {
        int minOffset = Integer.MAX_VALUE;
        Point nearestDeadBody = null;
        for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION + SHOOT_RANGE; x++) {
            for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION + SHOOT_RANGE; y++) {
                int offset = distanceFromCentre(x, y);
                PlayerId player = field[x][y];
                if (player != null && "DeadBody".equals(player.getName()) && offset < minOffset && 
                        !emptyDeadBodies.contains(player)) {
                    minOffset = offset;
                    nearestDeadBody = new Point(x, y);
                }
            }
        }
        return nearestDeadBody;
    }

    private boolean isEnemy(String name) {
        switch (name) {
            case "ZombieHater":
            case "DeadBody":
            case "EmoWolfWithGun": // don't bother shooting him
                return false;
            default:
                return true;
        }
    }
}

-1। कार्यान्वयन में भिन्न होते हुए, यह मेरे गॉर्डन फ्रीमैन के समान ही है ....
काइल कानोस

2
@KyleKanos। यह एक ही विचार है, लेकिन कार्यान्वयन विवरण गणना करते हैं। उदाहरण के लिए, जिन शवों की लूट हुई है, उन पर नज़र रखना एक उदाहरण है।
जेम्स_पिक

ओह, और लूट पर नज़र रखने के विषय पर, PlayerIdएक उपयुक्त कार्यान्वयन होता है equalsऔर hashCodeएक खिलाड़ी के "जीवन" के दौरान एक ही रहता है (यह केवल तब बदल जाता है जब वे मर जाते हैं या बदल जाते हैं), इसलिए आपको निरपेक्ष की तुलना PlayerIdमें एस रखना आसान हो सकता है emptyDeadBodiesपदों।
जेम्स_पिक

@KyleKanos अपने तर्क की नकल करना मेरा उद्देश्य कभी नहीं था। मैंने जो कुछ किया, वह मुझे अपना बॉट बनाने का था, मुझे लगता है कि यह सबसे अच्छा होगा।
कॉमनग्यू जूल 22'14

1
अच्छा मॉड! मुझे चिंता होने लगी थी कि ज्यादातर रणनीतियां मूल रूप से एक जैसी थीं, लेकिन उस आंदोलन यादृच्छिकता ने आपको भारी बढ़ावा दिया है!
जेम्स_पिक

6

वोर्टाइगंट

हमेशा डॉक्टर गॉर्डन फ्रीमैन का अनुसरण करेंगे, या यदि वह समान आयाम पर नहीं है, तो लक्ष्यहीन रूप से घूमें।

package player;

import java.util.ArrayList;

import zombie.*;

public class Vortigaunt implements Player {
    class PlayerLocation {
        private int x;
        int y;
        PlayerId player;

        public PlayerLocation(int x, int y, PlayerId id) {
            this.x = x;
            this.y = y;
            this.player = id;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public PlayerId getPlayer() {
            return player;
        }
    }
    @Override
    public Action doTurn(PlayerContext context) {
        PlayerId[][] field = context.getPlayField();
        PlayerLocation me = new PlayerLocation(context.getX(), context.getY(), context.getId());
        ArrayList<PlayerLocation> freemans = findFreeman(field);
        PlayerLocation nearestFreeman = getNearestFreeman(freemans, me);
        if (nearestFreeman == null) {
            return Move.randomMove();
        } else {
            return Move.inDirection(nearestFreeman.getX(), nearestFreeman.getY());
        }
    }

    private PlayerLocation getNearestFreeman(ArrayList<PlayerLocation> freemans, PlayerLocation me) {
        double nearestDistance = Integer.MAX_VALUE;
        PlayerLocation nearestFreeman = null;
        for (PlayerLocation freeman : freemans) {
            int x = freeman.getX() - me.getX();
            int y = freeman.getY() - me.getY();
            double distance = (int)Math.sqrt((double)(x * x + y * y));
            if (distance < nearestDistance) {
                nearestDistance = distance;
                nearestFreeman = freeman;
            }
        }
        return nearestFreeman;
    }

    private ArrayList<PlayerLocation> findFreeman(PlayerId[][] field) {
        ArrayList<PlayerLocation> freemans = new ArrayList<PlayerLocation>();
        for (int x = field.length; x >= 0; x -= 1) {
            for (int y = field[x].length; y >= 0; y -= 1) {
                if (field[x][y].getName().equals("GordonFreeman")) {
                    freemans.add(new PlayerLocation(x, y, field[x][y]));
                }
            }
        }
        return freemans;
    }

}

तो आप कभी गोली नहीं मारते ... लेकिन किसी ऐसे व्यक्ति के करीब रहना जो मैं करता हूं ... मैं यह नहीं बता सकता कि क्या यह फ्रीमैन को मारा जाएगा लेकिन यह ज़ोंबी आबादी के लिए बहुत बढ़िया होगा ...
kaine

6

कोकून - फ्रीज

कितनी शर्म की बात है। आधा दर्जन भाषाओं को चुनने के लिए, और हर कोई सिर्फ जावा का उपयोग करता है। खैर, उन्हें बेकार जाने देने में कोई समझदारी नहीं है, इसलिए यहां फ्रीज में एक प्रतियोगी है।

यह डायजेक्स्ट्रा के एल्गोरिथ्म का उपयोग करता है ताकि एकांत स्थान का पता लगाने के लिए एक सुनसान जगह का पता लगाया जा सके, अगर वह बाहर निकलता है तो गोलियों के लिए मजबूर हो जाता है, और यदि वे बहुत करीब आते हैं तो लाश को गोली मारते हैं।

अपडेट किया गया

कोकून अब उन मार्गों की अनदेखी करता है जो इसे अपने रूटिंग एल्गोरिदम में लाश की हड़ताली दूरी के भीतर ले जाते हैं, और 3 के बजाय 2 वर्गों के भीतर लाश को गोली मारते हैं (एक तंग कोकून बनाने के लिए)।

module player.Cocoon where
  import zombie.FregeBindings
  import frege.data.TreeMap
  import Data.List(sortBy)
  import Data.Foldable(minimumBy, maximumBy)

  instance Ord PlayerId where
    a <=> b = case a.getName <=> b.getName of
      Eq -> a.getNumber <=> b.getNumber
      x -> x

  instance Show Action where
    show action = action.toString

  -- Dijkstras shortest path algorithm
  data DijkstraNode = Green {d :: Int, pos :: (Int, Int)} | Red {pos :: (Int, Int)} | Yellow {d :: Int, pos :: (Int, Int)}
  data DijkstraState = DijkstraState {board :: Tree (Int, Int) DijkstraNode, yellows :: TreeSet DijkstraNode}
  derive Eq DijkstraNode
  derive Ord DijkstraNode
  derive Show DijkstraNode
  derive Show DijkstraState

  updateState :: Int -> DijkstraState -> (Int, Int) -> DijkstraState
  updateState d (oldState@DijkstraState {board, yellows}) pos  = case (lookup board pos) of
    Nothing -> oldState
    Just Green {d, pos} -> oldState
    Just Red {pos} -> let
        newYellow = Yellow d pos
        newYellows = insert yellows newYellow ()
        newBoard = update board pos newYellow
      in DijkstraState {board = newBoard, yellows = newYellows}
    Just (oldYellow@Yellow {d = oldD, pos = oldPos})
          | oldD <= d = oldState
          | true = let
              newYellow = Yellow d pos
              newYellows = insert (delete yellows oldYellow) newYellow ()
              newBoard = insert board pos newYellow
            in DijkstraState {board = newBoard, yellows = newYellows}

  neighbours :: (Int, Int) -> [(Int, Int)]
  neighbours (x,y) = [(x1 + x, y1 + y) | x1 <- [-1 .. 1], y1 <- [-1 .. 1], x1 != 0 || y1 != 0]

  moveRegion = [(x, y) | x <- [-1 .. 1], y <- [-1 .. 1]]

  findMove :: DijkstraState -> Maybe Move
  findMove DijkstraState {board, yellows}
     | null yellows = Nothing
     | true = let
         tip@Yellow{d, pos} = head (keys yellows)
         rest = delete yellows tip
         newBoard = insert board pos (Green d pos)
         intermediateState = DijkstraState {board = newBoard, yellows = rest}
         neighbourhood = [node | pos <- moveRegion , node <- lookup board pos]
       in if tip.pos == (0, 0)
          then case minimum neighbourhood of
            _ | null neighbourhood = Nothing
            Green {d, pos = (x,y)} -> Just (Move.inDirection x y)
            _ -> Nothing
          else findMove (fold (updateState (d + 1)) intermediateState (neighbours pos))

  insertRed :: Tree (Int, Int) DijkstraNode -> (Int, Int) -> Tree (Int, Int) DijkstraNode
  insertRed board pos = insert board pos (Red {pos})

  removeZombieTerritory :: PlayerContext -> Tree (Int, Int) DijkstraNode -> Tree (Int, Int) DijkstraNode
  removeZombieTerritory ctx board =
    let
      zombies = [pos | pos@(x,y) <- v2, pid <- ctx.lookAround x y, pid.getName == "Zombie"]
      zombieTerritory = [(x + xx, y + yy) | (x,y) <- zombies, xx <- [-2..2], yy <- [-2..2]]
    in fold Tree.delete board zombieTerritory

  v = [-visionRange .. visionRange]
  v2 = sortBy (comparing dist) [(x,y) | x <- v, y <- v]

  shootable = sortBy (comparing dist) [(x, y) | x <- [-shootRange .. shootRange], y <- [-shootRange .. shootRange]]

  moveTo :: (Int, Int) -> PlayerContext -> Maybe Move
  moveTo pos ctx =
    let
      rawBoard = fold insertRed Tree.empty ([p | p@(x, y) <- v2,
                                                  ctx.lookAround x y == Nothing] ++ [(0,0)])
      board = removeZombieTerritory ctx rawBoard
      yellows = Tree.insert Tree.empty (Yellow {d = 0, pos}) ()
    in findMove (DijkstraState {board, yellows})

  dist :: (Int, Int) -> Int
  dist (x,y) = max (abs x) (abs y)

  findBullets :: PlayerContext -> TreeSet PlayerId -> Maybe Action
  findBullets ctx emptyBodies =
    if (ctx.getBullets > 0) then Nothing
    else
      let
        viableBodies = [pos | pos@(x,y) <- v2, pid <- (ctx.lookAround x y), pid.getName == "DeadBody", lookup emptyBodies pid == Nothing]
      in case viableBodies of
         target : _ -> moveTo target ctx
         _ -> Nothing

  isThreat :: String -> (Int, Int) -> Bool
  isThreat name pos = case (name, pos) of
    ("Zombie", pos) | dist pos <= 2 -> true
    ("HideyTwitchy", _) -> true
    ("ZombieHater", _) -> true
    ("ZombieRightsActivist", _) -> true
    ("Gunner", _) -> true
    _ -> false

  shootThreats :: PlayerContext -> Maybe Action
  shootThreats ctx =
    let
      threats = [pid | pos@(x, y) <- shootable, pid <- ctx.lookAround x y, isThreat (pid.getName) pos]
    in case threats of
      target:_ | ctx.getBullets == 0 = Nothing
               | true = Just (Shoot.new target)
      _ -> Nothing

  coziness :: PlayerContext -> (Int, Int) -> Int
  coziness ctx (x,y) =
    let
      wallScores = [3 - dist (xx, yy) | xx <- [-2 .. 2],
                                        yy <- [-2 .. 2],
                                        xx != 0 || yy != 0,
                                        pid <- ctx.lookAround (x + xx) (y + yy),
                                        pid.getName == "DeadBody"]
    in 3 * sum wallScores - dist (x,y)

  gotoCoziest :: PlayerContext -> Maybe Action
  gotoCoziest ctx =
    let
      emptySquares = [pos | pos@(x, y) <- v2, ctx.lookAround x y == Nothing] ++ [(0,0)]
      coziest = maximumBy (comparing (coziness ctx)) emptySquares
    in if null emptySquares then Nothing
       else moveTo coziest ctx

  updateEmptyBodies :: PlayerContext -> TreeSet PlayerId -> TreeSet PlayerId
  updateEmptyBodies ctx current =
    let
      nearbyBodies = [pid | (x,y) <- neighbours (0,0), pid <- ctx.lookAround x y, pid.getName == "DeadBody"]
    in fold (\x -> \y -> insert x y ()) current nearbyBodies

  doStep :: TreeSet PlayerId -> PlayerContext -> Continue
  doStep !bodies ctx =
    let
      emptyBodies = updateEmptyBodies ctx bodies
      plan = (findBullets ctx emptyBodies) `mplus` (shootThreats ctx) `mplus` (gotoCoziest ctx)
    in case plan of
      Just action -> Continue {result = action, andThen = doStep emptyBodies}
      Nothing -> Continue {result = Move.stay, andThen = doStep emptyBodies}

  doTurn = doStep Tree.empty

4

गनर - जावा

आपको ब्लॉक से बाहर निकालने के लिए एक उदाहरण दिया गया है। वह जो कुछ भी देखता है उसे गोली मारता है, या बिना किसी चीज के चारों ओर घूमता है, या फिर उसे कोई गोलियां नहीं मिलीं।

package player;

import zombie.*;

public class Gunner implements Player {

    @Override
    public Action doTurn(PlayerContext context) {
        if (context.getBullets() > 0) {
            for (PlayerId player: context.shootablePlayers()) {
                switch(player.getName()) {
                    case "Gunner":
                    case "DeadBody":
                        break;
                    default:
                        return new Shoot(player);
                }
            }
        }
        return Move.randomMove();
    }

}

क्या आप इससे बेहतर कर सकते हैं?


3

HideyTwitchy

नुटजॉब जब तक कि कोई खिलाड़ी उसे शूटिंग रेंज में नीचे नहीं ले जाता है, तब तक वह हर चीज से छिपता है, जिस स्थिति में वह घबराता है और शूटिंग करता है (अपने खुद के सहित)। केवल शरीर को लूटता है यदि वह बारूद से बाहर निकलता है, तो लाशों से दूर हो जाता है।

package player;

import static java.lang.Math.*;
import java.awt.Point;
import java.util.HashSet;
import java.util.Set;

import zombie.*;
import static zombie.Constants.*;

public class HideyTwitchy implements Player {

    private Set<Integer> lootedCorpseIds = new HashSet<Integer>();

    @Override
    public Action doTurn(PlayerContext context) {
        Action action = null;

        Point playerP = getClosestPlayerPoint(context);
        Point corpseP = getClosestCorpsePoint(context); 
        Point enemyP = getClosestEnemyPoint(context);

        if (isWithinArea(playerP, Constants.SHOOT_RANGE, Constants.SHOOT_RANGE)) {
            //player spotted within 5x5
            if (context.getBullets() > 0) {
                action = getShootAction(playerP, context); //shoot!
            } else {
                action = getMoveAwayFromPoint(playerP); //run!
            }
        } else if (isWithinArea(enemyP, Constants.VISION_RANGE, Constants.VISION_RANGE)) {
            //players or zombie spotted within 8x8
            action = getMoveAwayFromPoint(enemyP); //run!
        } else if (isWithinArea(corpseP, Constants.VISION_RANGE, Constants.VISION_RANGE)) {
            //corpse spotted within 8x8

            int uniqueCorpseId = getPlayerIdAtPoint(context, corpseP).getNumber();
            if (isWithinArea(corpseP, 1, 1)) {
                //loot the corpse and get the heck away from it
                lootedCorpseIds.add(uniqueCorpseId);
                action = getMoveAwayFromPoint(corpseP);
            } else if (context.getBullets() == 0 && !lootedCorpseIds.contains(uniqueCorpseId)) {
                action = getMoveTowardsPoint(corpseP); //loot corpse if not looted!
            } 
        } else {
            //randomly move
            action = Move.randomMove();
        }

        return action;
    }

    private PlayerId getPlayerIdAtPoint(PlayerContext context, Point p) {
        return context.getPlayField()[(int) p.getX()][(int) p.getY()];
    }

    private Move getMoveTowardsPoint(Point p) {
        return Move.inDirection((int)p.getX() - CENTRE_OF_VISION, (int)p.getY() - CENTRE_OF_VISION);
    }

    private Move getMoveAwayFromPoint(Point p) {
        return Move.inDirection(CENTRE_OF_VISION - (int)p.getX(), CENTRE_OF_VISION - (int)p.getY());
    }

    private Shoot getShootAction(Point p, PlayerContext context) {
        PlayerId id = context.getPlayField()[(int) p.getX()][(int) p.getY()];
        Shoot shootAction = new Shoot(id);

        return shootAction;
    }

    private boolean isWithinArea(Point p, int x, int y) {
        return p != null 
                && abs(CENTRE_OF_VISION - p.getX()) <= x
                && abs(CENTRE_OF_VISION - p.getY()) <= y;
    }

    private Point getClosestEnemyPoint(PlayerContext context) {
        String[] lookFor = {};
        String[] avoid = {Dead.DEADBODYNAME};
        Point p = getClosestEntity(context, lookFor, avoid);

        return p;
    }

    private Point getClosestPlayerPoint(PlayerContext context) {
        String[] lookFor = {};
        String[] avoid = {Dead.DEADBODYNAME, Dead.ZOMBIENAME};
        Point p = getClosestEntity(context, lookFor, avoid);

        return p;
    }

    private Point getClosestCorpsePoint(PlayerContext context) {
        String[] lookFor = {Dead.DEADBODYNAME};
        String[] avoid = {Dead.ZOMBIENAME};
        Point p = getClosestEntity(context, lookFor, avoid);

        return p;
    }

    private Point getClosestEntity(PlayerContext context, String[] lookFor, String[] avoid) {

        int bestDistance = Integer.MAX_VALUE;
        Point closestPoint = null;

        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {


                PlayerId playerAtLocation = context.getPlayField()[x][y];

                if (playerAtLocation != null && !playerAtLocation.equals(context.getId())) {
                    //not empty and not me

                    boolean conditionsMet = true;
                    for (String lookForName : lookFor) {
                        conditionsMet |= playerAtLocation.getName().equals(lookForName);
                    }

                    for (String avoidName : avoid) {
                        conditionsMet &= !playerAtLocation.getName().equals(avoidName);
                    }

                    if (conditionsMet) {
                        int distance = max(abs(x - CENTRE_OF_VISION), abs(y - CENTRE_OF_VISION));
                        if (distance < bestDistance) {
                            bestDistance = distance;
                            closestPoint = new Point(x, y);
                        }
                    }
                }
            }
        }

        return closestPoint;
    }
}

3

SuperCoward - JAVA मुझे दोहरे सबमिशन के बारे में पता है लेकिन मैं अभी विरोध नहीं कर सका। कृपया मुझे बताएं कि क्या मुझे इसे हटा देना चाहिए।

वह किस तरह का कायर है जो गोली मारता है और लड़ता है? आपके सामने सुपर कायर को पेश करते हुए , वह इस क्षेत्र में दौड़ने से बचने की कोशिश करेगा कि वह कौन दुश्मन और लाश है। वह सुरक्षित रहने की कोशिश करता है और बाधाओं से बचता है। अगर उसे कोई अच्छा रास्ता नहीं सूझ रहा है, तो वह भाग-दौड़ कर रहा है

package player;

import zombie.*;
import static zombie.Constants.*;

import static java.lang.Math.abs;
import static java.lang.Math.max;

import java.awt.Point;

public class SuperCoward implements Player {

    private enum DANGER{
        SAFE(0),PROBABLY_SAFE(1),UNSAFE(2),DANGER(3);

        private int value;
        private DANGER(int value){
            this.value = value;
        }
    }

    private final int PLAYER_X = 8;
    private final int PLAYER_Y = 8;

    @Override
    public Action doTurn(PlayerContext context) {

        DANGER danger = DANGER.DANGER;
        Point position = null;
        for(int i=-1;i<1;i++){
            for(int j=-1;j<1;j++){
                DANGER positionDanger = isDangerous(context,PLAYER_X+i,PLAYER_Y+j);
                if(positionDanger.value < danger.value){
                    if(canMove(context,PLAYER_X+i,PLAYER_Y+j)){
                        position = new Point(PLAYER_X+i, PLAYER_Y+j);
                    }
                }
            }
        }

        if(position != null){
            return Move.inDirection(position.x, position.y);
        }else{
            return Move.STAY;
        }
    }

    private boolean canMove(PlayerContext context,int posX, int posY){
         PlayerId playerAtLocation = context.getPlayField()[posX][posY];
        if(playerAtLocation == null){
            return true;
        }else{
            return false;
        }
    }

    private DANGER isDangerous(PlayerContext context,int posX, int posY){
        DANGER danger = DANGER.SAFE;

          for (int x = 0; x < VISION_WIDTH; x++) {
                for (int y = 0; y < VISION_WIDTH; y++) {
                     PlayerId playerAtLocation = context.getPlayField()[x][y];

                     if(playerAtLocation != null && isEnemy(playerAtLocation.getName())){
                         int distanceToPlayer = max(abs(x - posX), abs(y - posY));
                         if(playerAtLocation.getName().equals("Zombie")){
                             DANGER currentDanger = null;
                             if(distanceToPlayer <=3){
                                 currentDanger = DANGER.DANGER;
                             }else if(distanceToPlayer <=5){
                                 currentDanger = DANGER.PROBABLY_SAFE;
                             }else if(distanceToPlayer >5){
                                 currentDanger = DANGER.SAFE;
                             }
                             if(currentDanger.value > danger.value){
                                 danger = currentDanger;
                             }
                         }else{
                             DANGER currentDanger = null;
                             if(distanceToPlayer <=5){
                                 currentDanger = DANGER.DANGER;
                             }else if(distanceToPlayer >5){
                                 currentDanger = DANGER.PROBABLY_SAFE;
                             }
                             if(currentDanger.value > danger.value){
                                 danger = currentDanger;
                             }
                         }
                     }
                }
          }
        return danger;
    }

    private boolean isEnemy(String name){
         switch(name) {
            case "DeadBody":
            case "GordonFreeman":
            case "EmoWolfWithAGun":
            case "HuddleWolf":
            case "ThePriest":
            case "Shotguneer":
            case "SuperCoward":
                return false;
            default:
                return true;
         }
    }
}

मेरी वर्तमान सोच यह है कि जब तक उनके बीच कोई मिलीभगत नहीं होती है, तब तक मैं डबल सबमिशन की अनुमति दूंगा - इसलिए ऐसी प्रविष्टियाँ जो आसानी से विभिन्न खिलाड़ियों द्वारा प्रस्तुत की जा सकती हैं, ठीक हैं, लेकिन गुर्गे या लैपडॉग नहीं हैं। ऐसा लगता है कि यह ठीक होना चाहिए (जब तक कि कोई वस्तु नहीं), इसलिए मुझे मौका मिलने पर मैं इसका परीक्षण करूंगा।
जेम्स_पिक

3
+1 के लिएDANGER danger = DANGER.DANGER;
आंद्रे at कोस्टीर्का

3

Shotguneer

मैं स्वीकार करूंगा कि गनर को गोली मारना मेरा मुख्य लक्ष्य है।

package player;

import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class Shotguneer implements Player {

    @Override
    public Action doTurn(PlayerContext context) {

        double sdistance=1000;

        if (context.getBullets() > 0) {
            for (PlayerId player: context.shootablePlayers()) {
                switch(player.getName()) {
                    case "Gunner":
                    case "ZombieRightsActivist":
                    case "HideyTwitchy":
                    case "ZombieHater":
                    case "Waller";
                    case "Bee";
                    case "SunTzu";
                    //case "Fox":
                    //case "Coward":
                        return new Shoot(player);
                    default:
                        break;
                }
            }
            boolean zombies=false;
            PlayerId TargetZombie = context.getId();
            for (int x = -3; x < +4; x++) {
            for (int y = -3; y < +4; y++) {
                double distance = sqrt(pow(x,2)+pow(y,2));
                PlayerId playerAtLocation = context.getPlayField()[x + CENTRE_OF_VISION][y + CENTRE_OF_VISION];
                if (playerAtLocation != null && playerAtLocation.getName().equals("Zombie") && (distance < sdistance ||zombies==false)) {
                    sdistance = distance;
                    zombies=true;
                    TargetZombie=playerAtLocation;
                }
                //if (playerAtLocation != null && playerAtLocation.getName().equals("Priest") && distance < 2 &&zombies==false) {
                    //TargetZombie=playerAtLocation;
                    //sdistance=distance;
                //}
            }}
            if (zombies || sdistance<3) {
                return new Shoot(TargetZombie);
            }
        }

        if (context.getPlayField()[CENTRE_OF_VISION-1][CENTRE_OF_VISION-1]==null){
            return Move.NORTHWEST;  
        } else if (context.getPlayField()[CENTRE_OF_VISION][CENTRE_OF_VISION-1]==null){
            return Move.NORTH;
        } else {
            return Move.WEST;
        }

    }

}

@ बेनी आप कैसे करते हैं ताकि आपको अब और संपादित न करना पड़े?
किन्नर

जैसा कि यह खड़ा है, यह संकलन नहीं करता है। मेरे पास इसे ठीक करने के लिए गया था, लेकिन कुछ स्थान हैं जहां मैं यह पता नहीं लगा सकता कि कोड का मूल इरादा क्या था (उदाहरण के लिए, कंपाइलर शिकायत करता है कि TargetZombieशायद इसे शुरू नहीं किया जा सकता है, और मुझे यकीन नहीं है कि क्या है तुम करना चाहोगे)। क्या आप उस पर एक और स्विंग लेना चाहते हैं?
जेम्स_पिक

कोशिश करने के लिए शुक्रिया। मैंने आपका कोड सेट नहीं किया था, इसलिए यह विफल हो गया क्योंकि यह आपके स्थिरांक को पहचान नहीं पाया। मुझे याद नहीं था कि अगर संकलनकर्ता के पास डिफ़ॉल्ट मान नहीं है, तो यह संकलित नहीं करेगा (हालांकि इसका उपयोग कभी नहीं किया जाएगा यदि यह लाश के लिए धन्यवाद नहीं था)। मैं इसे संशोधित किया है तो यह मुझे मारता है अगर मैं उस पर गलत हूँ! जब तक आप ऊब नहीं जाते हैं, तब तक आप इसे संपादित करने की कोशिश में समय बर्बाद न करें, मैं एक और टिप्पणी लिखूंगा यदि मैं पुष्टि कर सकता हूं कि यह अन्य खिलाड़ियों के साथ काम करता है।
कीन जूल

मैंने इसे ठीक किया, इसलिए यह त्रुटियों के बिना संकलित और चलेगा - ज्यादातर "बंद CENTRE_OF_VISION" त्रुटियों से, और कुछ एनपीई। आपको यह देखने के लिए कि क्या आपकी उम्मीद है, यह देखने के लिए आपको रन ( jamespic.github.io/zchin/2014-07-23/0.html ) पर एक नज़र डालनी होगी
जेम्स_पिक

ऐसा लगता है कि आपने गनर की जीवन प्रत्याशा पर बड़ा प्रभाव डाला है! मुझे आश्चर्य है कि अगर यह एक दूसरे को बाहर ले जाने वाले शीर्ष प्रतियोगियों की लहर को चिंगारी देगा?
जेम्स_पिक

2

सोकी - जावा

सोकी जानती है कि आप पैक्स में बेहतर हैं, इसलिए वह अपने निकटतम सहयोगी के पास जाने की कोशिश करता है। चलते समय, यदि वह खतरे में है तो लड़ने की कोशिश करता है या अन्यथा दौड़ने की कोशिश करता है। जब वह दोस्तों के पास पहुंचता है, तो वे सभी एक साथ लड़ते हैं जब तक कि उनके पास कोई बारूद नहीं होता है, तब परिमार्जन करने के लिए निकटतम शरीर खोजने की कोशिश करें।

package player;

import zombie.*;
import static zombie.Constants.*;

import static java.lang.Math.abs;
import static java.lang.Math.max;

import java.awt.Point;
import java.util.HashMap;
import java.util.Map;

public class Sokie implements Player {

    public static Map<Point, Sokie> myPack = new HashMap<>();
    private PlayerContext context;
    private Move moveDirection;
    private final int PLAYER_X = 8;
    private final int PLAYER_Y = 8;

    private enum DANGER {
        SAFE(0), PROBABLY_SAFE(1), UNSAFE(2), DANGER(3);

        private int value;

        private DANGER(int value) {
            this.value = value;
        }
    }

    @Override
    public Action doTurn(PlayerContext context) {
        Point p = new Point(context.getX(), context.getY());
        myPack.put(p, this);
        this.context = context;

        int friends = 0;
        int deadbodyDistance = Integer.MAX_VALUE;
        Move deadbodyDirection = null;
        Point deadBodyPosition = null;
        Move friendsDirection = Move.SOUTHWEST;

        // Find the closest friend to whom we can move
        int maxDistance = Integer.MAX_VALUE;
        for (Sokie bp : myPack.values()) {
            // Skip ourselves
            if (bp.context.equals(context)) {
                continue;
            }
            Point pos = bp.getPosition();
            int x = pos.x;
            int y = pos.y;
            int distance = Math.max(Math.abs(context.getX() - x),
                    Math.abs(context.getY() - y));
            if (distance < maxDistance) {
                if (canMove(context, (int) Math.signum(x), (int) Math.signum(y))
                        && !isDangerous(context, (int) Math.signum(x),
                                (int) Math.signum(y))) {
                    maxDistance = distance;
                    friendsDirection = Move.inDirection((int) Math.signum(x),
                            (int) Math.signum(y));
                } else {
                    if (canMove(context, (int) Math.signum(0),
                            (int) Math.signum(y))
                            && !isDangerous(context, (int) Math.signum(x),
                                    (int) Math.signum(y))) {
                        maxDistance = distance;
                        friendsDirection = Move.inDirection(
                                (int) Math.signum(0), (int) Math.signum(y));
                    } else if (canMove(context, (int) Math.signum(x),
                            (int) Math.signum(0))
                            && !isDangerous(context, (int) Math.signum(x),
                                    (int) Math.signum(y))) {
                        maxDistance = distance;
                        friendsDirection = Move.inDirection(
                                (int) Math.signum(x), (int) Math.signum(0));
                    }
                }
            }
        }

        // Find how many friends we have in close vicinity
        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                PlayerId playerAtLocation = context.getPlayField()[x][y];
                if (playerAtLocation != null
                        && playerAtLocation.getName().equals("Sokie")) {
                    friends++;
                }
            }
        }

        // Search for dead bodies
        for (int y = 1; y < VISION_WIDTH - 1; y++) {
            for (int x = 1; x < VISION_WIDTH - 1; x++) {

                PlayerId playerAtLocation = context.getPlayField()[x][y];
                // find a dead body
                if ((playerAtLocation != null)
                        && "DeadBody".equals(playerAtLocation.getName())) {
                    // check adjacent squares for an empty square
                    for (int yy = -1; yy <= +1; yy++) {
                        for (int xx = -1; xx <= +1; xx++) {
                            PlayerId playerNearby = context.getPlayField()[x
                                    + xx][y + yy];
                            if (playerNearby == null) {
                                int distance = max(abs(xx + x
                                        - CENTRE_OF_VISION), abs(yy + y
                                        - CENTRE_OF_VISION));
                                if (distance < deadbodyDistance) {
                                    deadbodyDistance = distance;
                                    deadBodyPosition = getAbsolutePosition(
                                            context, x + xx, y + yy);
                                    deadbodyDirection = Move.inDirection(xx + x
                                            - CENTRE_OF_VISION, yy + y
                                            - CENTRE_OF_VISION);
                                }
                            }
                        }
                    }
                }
            }
        }

        // If we have atleast 2 people close, stay or try to shoot
        // otherwise move randomly, try to find bodies and packs
        if (friends >= 2) {
            // Shoot anybody close
            if (context.getBullets() > 0) {
                int distEnemy = VISION_WIDTH;
                int distZombie = VISION_WIDTH;
                PlayerId targetEnemy = null;
                PlayerId targetZombie = null;
                for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION
                        + SHOOT_RANGE; x++) {
                    for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION
                            + SHOOT_RANGE; y++) {
                        PlayerId player = context.getPlayField()[x][y];
                        if (player != null) {
                            int dist = getDistance(x, y);
                            if (player.getName().equals("Zombie")) {
                                if (dist < distZombie) {
                                    distZombie = dist;
                                    targetZombie = player;
                                }
                            } else if (isEnemy(player.getName())
                                    && dist <= distEnemy) {
                                distEnemy = dist;
                                targetEnemy = context.getPlayField()[x][y];
                            }
                        }
                    }
                }

                if (targetZombie != null && distZombie <= 2) {
                    return new Shoot(targetZombie);
                } else if (targetEnemy != null && distEnemy <= 5) {
                    return new Shoot(targetEnemy);
                }
            }

            for (Sokie bp : myPack.values()) {
                // If someone in the pack has ammo, stay
                if (bp.getAmmo() > 0) {
                    return Move.STAY;
                }
            }

            // If there are bodies close, try to reach them
            int bodyDistance = deadbodyDistance;
            if (deadbodyDistance <= 5) {
                for (Sokie bp : myPack.values()) {
                    int distanceBody = Math.max(
                            Math.abs(deadBodyPosition.x - bp.context.getX()),
                            Math.abs(deadBodyPosition.y - bp.context.getY()));
                    if (deadbodyDistance > distanceBody) {
                        bodyDistance = distanceBody;
                    }
                }
            }
            // If we are not the closest to the body, stay
            if (bodyDistance < deadbodyDistance) {
                return Move.STAY;
            } else {
                return deadbodyDirection;
            }
        } else {
            // We try to reach our closest friend
            // If we are in danger, either fight or run
            if (areWeInDanger(context, PLAYER_X, PLAYER_Y)) {
                if (context.getBullets() > 0) {
                    int distEnemy = VISION_WIDTH;
                    int distZombie = VISION_WIDTH;
                    PlayerId targetEnemy = null;
                    PlayerId targetZombie = null;
                    for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION
                            + SHOOT_RANGE; x++) {
                        for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION
                                + SHOOT_RANGE; y++) {
                            PlayerId player = context.getPlayField()[x][y];
                            if (player != null) {
                                int dist = getDistance(x, y);
                                if (player.getName().equals("Zombie")) {
                                    if (dist < distZombie) {
                                        distZombie = dist;
                                        targetZombie = player;
                                    }
                                } else if (isEnemy(player.getName())
                                        && dist <= distEnemy) {
                                    distEnemy = dist;
                                    targetEnemy = context.getPlayField()[x][y];
                                }
                            }
                        }
                    }

                    if (targetZombie != null && distZombie <= 2) {
                        return new Shoot(targetZombie);
                    } else if (targetEnemy != null && distEnemy <= 5) {
                        return new Shoot(targetEnemy);
                    }
                } else {
                    DANGER danger = DANGER.DANGER;
                    Point position = null;
                    for (int i = -1; i < 1; i++) {
                        for (int j = -1; j < 1; j++) {
                            DANGER positionDanger = getDangerLevel(context,
                                    PLAYER_X + i, PLAYER_Y + j);
                            if (positionDanger.value < danger.value) {
                                if (canMove(context, PLAYER_X + i, PLAYER_Y + j)) {
                                    position = new Point(PLAYER_X + i, PLAYER_Y
                                            + j);
                                }
                            }
                        }
                    }

                    if (position != null) {
                        return Move.inDirection(position.x, position.y);
                    } else {
                        return Move.randomMove();
                    }
                }
            } else {
                return friendsDirection;
            }
        }
        return Move.randomMove();
    }

    private DANGER getDangerLevel(PlayerContext context, int posX, int posY) {
        DANGER danger = DANGER.SAFE;

        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                PlayerId playerAtLocation = context.getPlayField()[x][y];

                if (playerAtLocation != null
                        && isEnemy(playerAtLocation.getName())) {
                    int distanceToPlayer = max(abs(x - posX), abs(y - posY));
                    if (playerAtLocation.getName().equals("Zombie")) {
                        DANGER currentDanger = null;
                        if (distanceToPlayer <= 2) {
                            currentDanger = DANGER.DANGER;
                        } else if (distanceToPlayer <= 5) {
                            currentDanger = DANGER.PROBABLY_SAFE;
                        } else if (distanceToPlayer > 5) {
                            currentDanger = DANGER.SAFE;
                        }
                        if (currentDanger.value > danger.value) {
                            danger = currentDanger;
                        }
                    } else {
                        DANGER currentDanger = null;
                        if (distanceToPlayer <= 5) {
                            currentDanger = DANGER.DANGER;
                        } else if (distanceToPlayer > 5) {
                            currentDanger = DANGER.PROBABLY_SAFE;
                        }
                        if (currentDanger.value > danger.value) {
                            danger = currentDanger;
                        }
                    }
                }
            }
        }
        return danger;
    }

    private boolean isDangerous(PlayerContext context, int posX, int posY) {

        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                PlayerId playerAtLocation = context.getPlayField()[x][y];

                if (playerAtLocation != null
                        && isEnemy(playerAtLocation.getName())) {
                    int distanceToPlayer = max(abs(x - posX), abs(y - posY));
                    if (playerAtLocation.getName().equals("Zombie")) {
                        if (distanceToPlayer <= 2) {
                            return true;
                        }
                    } else {
                        if (distanceToPlayer <= 5) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;

    }

    // calculates absolute position, from XY in our field of view
    private Point getAbsolutePosition(PlayerContext context, int relativeX,
            int relativeY) {
        int playerX = context.getX();
        int playerY = context.getY();

        return new Point(playerX + (relativeX - PLAYER_X), playerY
                + (relativeY - PLAYER_Y));
    }

    // Gets distance on the field
    private int getDistance(int x, int y) {
        return Math.max(Math.abs(PLAYER_X - x), Math.abs(PLAYER_Y - y));
    }

    public int getAmmo() {
        return context.getBullets();
    }

    public Point getPosition() {
        Point p = new Point(context.getX(), context.getY());
        return p;
    }

    public Move getMoveDirection() {
        return moveDirection;
    }

    // Quick check for dangers around us
    private boolean areWeInDanger(PlayerContext context, int posX, int posY) {
        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                PlayerId playerAtLocation = context.getPlayField()[x][y];

                if (playerAtLocation != null
                        && isEnemy(playerAtLocation.getName())) {
                    int distanceToPlayer = max(abs(x - posX), abs(y - posY));
                    if (playerAtLocation.getName().equals("Zombie")) {
                        if (distanceToPlayer <= 2) {
                            return true;
                        }
                    } else {
                        if (distanceToPlayer <= 5) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    private boolean canMove(PlayerContext context, int posX, int posY) {
        PlayerId playerAtLocation = context.getPlayField()[posX][posY];
        if (playerAtLocation == null) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isEnemy(String name) {
        switch (name) {
        case "Sokie":
        case "DeadBody":
        case "GordonFreeman":
        case "EmoWolfWithAGun":
        case "HuddleWolf":
        case "ThePriest":
        case "Shotguneer":
        case "StandStill":
            return false;
        default:
            return true;
        }
    }

}

FYI करें, आपके खिलाड़ी का नाम आपकी कक्षा के नाम के समान होगा (इस मामले में, "सोकी")। इसलिए मुझे संदेह है playerAtLocation.getName().equals("BetterInPacks2")कि शायद होना चाहिए playerAtLocation.getName().equals("Sokie")
जेम्स_पिक

डांग! जब मैं अलग-अलग कार्यान्वयन का परीक्षण कर रहा था, तो कुछ बचे हुए कोड थे, मैं इसे कुछ ही समय में ठीक कर दूँगा! धन्यवाद
सूकी

2

मधुमक्खी - अजगर

दूसरी प्रविष्टि, लेकिन मुझे लगा कि कुछ और बाहर और एक अलग भाषा में कोशिश करने में मज़ा आएगा।

  • अब मधुमक्खियां उसी स्थान पर जाने से बचेंगी।
  • अब और अधिक 'पायथोनिक'
  • ऑप्टिमाइज़्ड टोरस मूवमेंट ताकि मधुमक्खियों को क्वीन क्विकर मिल सके (धन्यवाद जेम्स ने बोर्ड साइज़ को एक्सेस करने की अनुमति दी)

मधुमक्खियां एक साथ रहना पसंद करती हैं, इसलिए वे जीवित मधुमक्खियों में से एक को रानी मधुमक्खी के रूप में नामित करती हैं और उसकी ओर झुका देती हैं। वे उसके रास्ते पर विरोधियों को डंक देंगे, मानव पर ज़ोंबी मांस पसंद करते हैं।

from zombie import Player, Move, Shoot, PlayerRegistry, Constants

friends = ['Bee','Waller','DeadBody','ThePriest','StandStill','Vortigaunt','EmoWolfWithAGun']
MID = Constants.CENTRE_OF_VISION
BOARDSIZE = 1
sign = lambda x: (1, -1)[x<0]
isZombie = lambda player: player and player.getName() is "Zombie"
isEnemy = lambda player: player and player.getName() not in friends
isWall = lambda player: player and (player.getName() is "DeadBody" or player.getName() is "StandStill")
distance = lambda x1,y1,x2,y2: max(distance1d(x1,x2), distance1d(y1,y2))
distance1d = lambda x1,x2: min(abs(x1-x2), BOARDSIZE - abs(x1-x2))
Bees = {}
Shot = set()
MoveTo = set()  

def getDirection(x1, x2):  
    diff = x1 - x2  
    if abs(diff) > (BOARDSIZE // 2):
        return sign(diff)
    return -sign(diff)

class Bee(Player):  
    Queen = None
    QueenBeePosition = None
    X = Y = ID = 0
    LastTurn = -1   

    def doTurn(self, context): 
        global BOARDSIZE
        self.ID = context.id.number
        self.X = context.x
        self.Y = context.y
        BOARDSIZE = context.boardSize  
        self.setQueenBee(context.gameClock)                    
        action = self.sting(context)
        if action:
            return action
        return self.moveToQueenBee(context)     

    def setQueenBee(self, turn):
        if turn != Bee.LastTurn:
            Bee.LastTurn = turn     
            MoveTo.clear() # Clear the move set on new turn
        Bees[self.ID] = turn # Report In        
        if not Bee.Queen or (Bee.Queen and Bees[Bee.Queen] < turn - 1):
            Bee.Queen = self.ID
            Bee.QueenBeePosition = (self.X, self.Y)     

    def moveToQueenBee(self, context):
        if self.ID == Bee.Queen:
            return Move.randomMove()

        dist = distance(Bee.QueenBeePosition[0], Bee.QueenBeePosition[1], self.X, self.Y)
        if dist < 4:
            return Move.randomMove()

        signX = getDirection(self.X, Bee.QueenBeePosition[0])      
        signY = getDirection(self.Y, Bee.QueenBeePosition[1])      
        walls = 0
        field = context.playField
        for (deltaX, deltaY) in [(signX,signY),(signX,0),(0,signY),(signX,-signY),(-signX,signY)]:
            player = field[MID + deltaX][MID + deltaY]
            if isWall(player):
                walls += 1
            if not player:               
                point = frozenset([self.X+deltaX,self.Y+deltaY])            
                if point not in MoveTo:
                    MoveTo.add(point)                   
                    return Move.inDirection(deltaX,deltaY)
        if walls > 2:
            return Move.randomMove()
        return Move.STAY

    def sting(self, context):      

        if context.bullets < 1:
            return      
        field = context.playField
        closestZombie,closestPlayer = None,None
        closestZombieDist,bestDist = 3,5   
        for x in range(MID - 5, MID + 5):
            for y in range(MID - 5, MID + 5):
                player = field[x][y]
                if player and not isWall(player) and player not in Shot:
                    dist = distance(MID,MID,x,y)
                    if isZombie(player) and dist < closestZombieDist:   
                        closestZombieDist = dist
                        closestZombie = player
                    elif isEnemy(player) and dist < bestDist: 
                        bestDist = dist
                        closestPlayer = player

        if closestZombie:
            Shot.add(closestZombie)
            return Shoot(closestZombie)        

        if closestPlayer:
            Shot.add(closestPlayer)
            return Shoot(closestPlayer)        

PlayerRegistry.registerPlayer("Bee", Bee())

1
ओह! मैं चिंता करने लगा था कि इस प्रतियोगिता में जावा के अलावा कुछ नहीं होगा।
जेम्स_पिक

हाँ, और पहली प्रविष्टि जो विश्व स्तर पर क्षेत्र को खोजती है, जो मुझे लगता है कि एक साफ-सुथरी विशेषता है।
मूप

एक चीज जो आपको उपयोगी लग सकती है, वह यह है कि जेथॉन स्वचालित रूप से प्रापर्टी के रूप में उपलब्ध जावाबीन के लिए गेटर्स और सेटर बनाता है। उदाहरण के लिए, आप इसके context.gameClockबजाय उपयोग कर सकते हैं context.getGameClock()
जेम्स_पिक

@James_pic टिप के लिए धन्यवाद, यह नहीं पता था।
मूर

2

श्री हत्यारे

उसके माता-पिता बहुत अच्छे लोग नहीं हैं। उसके पास हत्या करने के लिए कोई योग्यता नहीं है, लेकिन अगर उसे लगता है कि आप उसे लंबे समय तक जीने में मदद करेंगे। वह हर किसी के साथ ऐसा व्यवहार करता है जैसे कि वे विशेष हैं और फिर उसको नापसंद करता है और आपको यह बताता है कि वह आपको कितना निकट चाहता है, वह आपको कितना चाहता है और वर्तमान स्थिति के लिए महत्वपूर्ण है।

जैसा कि मुझे पता है कि इसमें से बहुत कुछ छिपा हुआ है जिसमें मैं कुछ समझाऊंगा। वह आमतौर पर उन लोगों को कभी नहीं मारता, जो उसकी धमकियों को मार सकते हैं, क्योंकि उन्हें अपने लक्ष्य नहीं हैं। वह कुछ ऐसे लोगों को खिलाएगा जो कभी गोली नहीं चलाते हैं। एक अपवाद के साथ, वह आपको मारता है यदि आप वर्तमान में उसे मारते हैं। वह बिना किसी कोड के जबरदस्ती किए गए स्थानों पर दीवारों को पसंद करता है। वह फॉक्स फोबिक और एक कायर कायर है। वह Huddlewolves के साथ cuddles और Wallers के साथ दीवारों। वह वर्तमान में ग्रुपर्स की ओर बढ़ता है (जैसे सोकी भले ही सोकी ने उसे निर्दयता से गोली मार दी)। नैश को उससे प्यार करना चाहिए क्योंकि उसकी प्राथमिकताएं एक गेम सिद्धांतवादी रोना है। उनके ग्राहक, हालांकि, बहुत ज़ेनोफोबिक लगते हैं, जिससे वे पुजारी, एलियंस और नवागंतुकों को मारते हैं (हालांकि वह आपको क्षमा करते हैं या यदि आप उसे नहीं मारते हैं तो शनिवार का दिन है ... रविवार बहुत देर हो चुकी है)। माफ़ करना अगर मैं किसी और को भूल रहा हूँ।

package player;
import zombie.*;
import static zombie.Constants.*;
//import static java.lang.Math.*;

public class Jack implements Player {
    @Override
    public Action doTurn(PlayerContext context) {
        int[] Ideal = {1,5,8,7,2,2,7,2,1,5,1,2,1,1,7,2,7,7,7,0,2,3,1,7};
        int[] Threat = {1,4,8,8,1,1,7,1,2,2,2,1,2,0,6,2,6,6,6,1,1,2,6,6};
        int[] Importance = {1,2,4,4,1,1,1,1,3,1,3,1,3,3,1,2,1,1,1,10,2,2,3,2};

        PlayerId Target = context.getId();
        int[][] Bob = {{800-2*Math.max(0,context.getGameClock()),400-Math.max(0,context.getGameClock()),800-Math.max(0,context.getGameClock())},{0,0,0},{0,0,0}};
        double maxDanger=0;
        int zombies=0;

        for (int x = -8; x < +8; x++) {
        for (int y = -8; y < +8; y++) {
            PlayerId playerAtLocation = context.getPlayField()[x + CENTRE_OF_VISION][y + CENTRE_OF_VISION];
            if (playerAtLocation != null && x*y+x+Math.abs(y) != 0){
                if (Math.abs(x)*Math.abs(y)==1 || Math.abs(x) + Math.abs(y)==1){
                    Bob[x+1][y+1]-=100000;
                }
                int dist = Math.max(Math.abs(x),Math.abs(y));
                int Ident = Dats(playerAtLocation);
                double Danger = (Threat[Ident]-dist)*Importance[Ident];
                if(Ident==1 && dist<Threat[Ident]){
                    zombies++;
                    if(context.getPlayField()[TFSAE(x)-1 + CENTRE_OF_VISION][TFSAE(y) -1+ CENTRE_OF_VISION]!=null){ 
                    Danger=0;
                                } else if(dist==2){Danger+=4;} 
                }
                if(Danger>maxDanger && dist<6){
                    maxDanger=Danger;
                    Target=playerAtLocation;
                }
                if(dist != Ideal[Ident]){

                    Bob[TFSAE(x)][TFSAE(y)] += Math.round(200*Importance[Ident]/(dist-Ideal[Ident]));

                    if(TFSAE(x) ==1) {
                        Bob[0][TFSAE(y)] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                        Bob[2][TFSAE(y)] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                    } else {
                        Bob[1][TFSAE(y)] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                    }

                    if(TFSAE(y) ==1) {
                        Bob[TFSAE(x)][0] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                        Bob[TFSAE(x)][2] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                    } else {
                        Bob[TFSAE(x)][1] += Math.round(100*Importance[Ident]/(dist-Ideal[Ident]));
                    }
                }
            }
        }}

        if (context.getBullets()>1 && maxDanger>0){
            return new Shoot(Target);
        } else if (context.getBullets()==1 && zombies>3){
            return new Shoot(context.getId());
        } else if (context.getBullets()==1 && maxDanger>7){
            return new Shoot(Target);
        }

        int Xmax=0;
        int Ymax=0;

        for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
            if (Bob[x][y]>=Bob[Xmax][Ymax]){
                Xmax=x;
                Ymax=y;
            }
        }}
        return Move.inDirection(Xmax-1, Ymax-1);

    }

    private int Dats (PlayerId WhoDat){
        switch (WhoDat.getName()){
            case "DeadBody": return 0;
            case "Zombie": return 1;
            case "Fox": return 2;
            case "Coward": return 3;
            case "Shotguneer": return 4;
            case "HuddleWolf": return 5;
            case "Sokie": return 6;
            case "GordonFreeman": return 7;
            case "Vortigaunt": return 8;
            case "SuperCoward": return 9;
            case "StandStill": return 10;
            case "JohnNash": return 11;
            case "MoveRandomly": return 12;
            case "Waller": return 13;
            case "HideyTwitchy": return 14;
            case "Bee": return 15;
            case "ZombieHater": return 16;
            case "ZombieRightsActivist": return 17;
            case "Gunner": return 18;
            case "EmoWolfWithAGun": return 19;
            case "Jack": return 20;
              case "SOS": return 21;
              case "SunTzu": return 22;
            default: return 23;
        }

    }
    private int TFSAE(int TBN){
        if(TBN==0){return 1;
        } else if(TBN>0){return 2;}

        return 0;
    }
}

ओह, हाँ, जैक वास्तव में अपने लिए आखिरी गोली बचा लेता है। अगर उसके आसपास एक निश्चित संख्या में लाश हैं और उसके पास एक गोली बची है तो वह फैलने से बचाने के लिए खुद को मार लेगा। चूंकि यह कोई फर्क नहीं पड़ता कि मैं जीतता हूं (मैं खुद को इनाम नहीं दे सकता) मैं चाहता था कि कुछ चरित्र उस कार्यक्षमता के हों।
17

@James_pic इस खेल में काम किया (हालांकि पिछले संस्करण में मैंने कुछ दिन पहले क्लोन किया था)। यह काम करना चाहिए। अगर यह मुझे पता नहीं है। यदि यह रविवार को नहीं है तो इसे हटा दें।
kaine

यह कोड के वर्तमान संस्करण में ठीक काम करने लगता है। मैं इसे आज बाद में एक परीक्षण में शामिल करूँगा।
जेम्स_पिक

फिर से, मुझे नहीं पता कि यह प्रविष्टि कैसे काम करती है। अगर किसी और ने इसे जमा किया था, तो मुझे लगता है कि यह गैर-काम करने वाली बकवास थी, लेकिन चूंकि शॉटगनर वर्तमान में मेरी सर्वश्रेष्ठ प्रविष्टि को हरा रहा है, मैं वास्तव में यह देखने के लिए उत्सुक हूं कि यह वास्तव में क्या करता है।
जेम्स_पिक

सुंदर जटिल और, मैं मानती हूं, खतरे / दूरी / प्राथमिकता प्रबंधन।
थाइलॉन

1

एसओएस (शूट ऑन साइट)

package player;

import zombie.*;
import static zombie.Constants.*;
import static java.lang.Math.*;

public class SOS implements Player {

    @Override
    public Action doTurn(PlayerContext context) {
        if (context.getBullets() > 0) {
            for (PlayerId player: context.shootablePlayers()) {
                switch(player.getName()) {
                    case "Gunner":
                    case "Zombie":
                    case "ZombieRightsActivist":
                        return new Shoot(player);
                    default:
                        break;
                }
            }
        }
        Move bestDirection = Move.NORTH;
        int bestDistance = Integer.MAX_VALUE;
        for (int x = 0; x < VISION_WIDTH; x++) {
            for (int y = 0; y < VISION_WIDTH; y++) {
                int distance = max(abs(x - CENTRE_OF_VISION), abs(y - CENTRE_OF_VISION));
                PlayerId playerAtLocation = context.getPlayField()[x][y];
                if (playerAtLocation != null
                        && !(playerAtLocation.getName().equals("Zombie"))
                        && !(playerAtLocation.getName().equals("Gunner"))
                        && !(playerAtLocation.getName().equals("ZombieRightsActivist"))
                        && !(playerAtLocation.getName().equals("ZombieHater"))
                        && !(playerAtLocation.equals(context.getId()))
                        && distance < bestDistance) {
                    bestDistance = distance;
                    bestDirection = Move.inDirection(x - CENTRE_OF_VISION, y -CENTRE_OF_VISION);
                }
            }
        }
        return bestDirection;
    }
}

1

जॉन नैश - जावास्क्रिप्ट

निर्णय कि क्या किसी को गोली मारना अनिवार्य रूप से कैदी की दुविधा है। यदि आप मानते हैं कि आपकी विरोधी ने पहले ही अपना मन बना लिया है, तो हमेशा सबसे अच्छा विकल्प उन्हें गोली मारना है। हालांकि, यदि आपकी विरोधी यह तय करेगी कि वे क्या सोचते हैं, उसके आधार पर आपको क्या करना है, तो सबसे अच्छा विकल्प उन्हें छोड़ना होगा, और वे शायद ऐसा ही करेंगे।

जॉन नैश केवल "चंप्स" को गोली मारते हैं - विरोधी जो पहले से ही अपना मन बना चुके हैं। यही है, वह हमेशा शूटिंग करने वाले सलाहकारों को गोली मारता है, या कभी गोली न चलाने वाले विरोधियों को गोली मारता है। यदि उनके पास अधिक जटिल तर्क है तो वह विपक्षी को अकेला छोड़ देता है।

जब वह शूटिंग नहीं कर रहा होता है, तो वह गोलियों या दक्षिण की ओर बढ़ रहा होता है।

var Constants = Packages.zombie.Constants
var Shoot = Packages.zombie.Shoot
var Move = Packages.zombie.Move
var Player = Packages.zombie.Player
var PlayerRegistry = Packages.zombie.PlayerRegistry

function mkSet() {
    var s = {}
    for (var i = 0; i < arguments.length; i++) {
        s[arguments[i]] = true
    }
    return s
}

var chumps = mkSet(
                "GordonFreeman",
                "HideyTwitchy",
                "Gunner",
                "MoveRandomly",
                "StandStill",
                "ThePriest",
                "Vortigaunt",
                "ZombieHater",
                "ZombieRightsActivist",
                "Bee",
                "Zombie",
                "SuperCoward"
              )

function dist(x, y) {
    return Math.max(Math.abs(x - Constants.CENTRE_OF_VISION), Math.abs(y - Constants.CENTRE_OF_VISION))
}

function range(width, offset) {
    var x = []
    for (var i = -width; i <= width; i++) {
        for (var j = -width; j <= width; j++) {
            if (i != 0 || j != 0) x.push([i + offset,j + offset])
        }
    }
    return x
}

function JohnNash() {
    var looted = {}
    this.doTurn = function(context) {
        var field = context.getPlayField()
        // Save looted bodies
        range(1, Constants.CENTRE_OF_VISION).forEach(function(p) {
            var x = p[0], y = p[1]
            var playerId = field[x][y]
            if (playerId && playerId.getName() == "DeadBody") {
                looted[playerId] = true
            }
        })

        // Shoot any nearby chumps
        if (context.getBullets() > 0) {
            var shootableIterator = context.shootablePlayers().iterator();
            while (shootableIterator.hasNext()) {
                var shootable = shootableIterator.next()
                if (chumps[shootable.getName()]) return new Shoot(shootable)
            }
        }

        // Helper function - everyone loves closures
        function moveTowards(x, y) {
            var tryMove = Move.inDirection(
                    x - Constants.CENTRE_OF_VISION,
                    y - Constants.CENTRE_OF_VISION
            )
            if (!(field[Constants.CENTRE_OF_VISION + tryMove.x][Constants.CENTRE_OF_VISION + tryMove.y])) {
                return tryMove
            } else {
                // If your path is blocked, take a random move
                return Move.randomMove()
            }
        }

        // Loot
        var bestX, bestY, bestDist = Infinity
        range(Constants.VISION_RANGE, Constants.CENTRE_OF_VISION).forEach(function(p) {
            var x = p[0], y = p[1]
            var playerId = field[x][y]
            if (playerId
                    && playerId.getName() == "DeadBody"
                    && !looted[playerId]
                    && dist(x, y) < bestDist) {
                bestDist = dist(x,y)
                bestX = x
                bestY = y
            }
        })

        if (bestDist < Infinity) {
            return moveTowards(bestX, bestY)
        }
        else return Move.SOUTH
    }
}

PlayerRegistry.registerPlayer("JohnNash", new Player(new JohnNash()))

MoveRandomly यादृच्छिक रूप से आगे बढ़ने के अलावा कुछ भी करता है?
थाइलॉन

@ थाइलैंड नोप, यह टिन पर जैसा कहता है, वैसा ही करता है। मूप ने इसे परियोजना में भेजे गए एक अनुरोध में शामिल किया। पुल अनुरोध का मुख्य उद्देश्य HTML आउटपुट में सुधार करना था, लेकिन इसमें MoveRandomly भी शामिल था, और मुझे लगा कि मैं टेस्ट में MoveRandomly को परीक्षण में शामिल करने के लिए देखूंगा।
जेम्स_पिक

मैंने आपके गितुब से नवीनतम खींच लिया और संकलन करने के लिए john-nash.js प्राप्त नहीं कर सका
Moop

@ मुझे भी वही मिला।
प्योरफेरेट

ठीक कर दिया। मैंने इसे केवल जावा 7 के खिलाफ परीक्षण किया था। इसे 8 में भी काम करना चाहिए
जेम्स_पिक

1

SunTzu सामरिक होने की कोशिश करता है, और स्थानांतरित करने के लिए ग्रिड पर सुरक्षित स्पॉट ढूंढता है। लेकिन जैसा कि यह खड़ा है, वह सिर्फ प्रगति में एक काम है।

इस प्रकार, हम जान सकते हैं कि जीत के लिए पाँच आवश्यक हैं:
1. वह जीतेगा जो जानता है कि कब लड़ना है और कब नहीं लड़ना है।
2. वह जीत जाएगा जो जानता है कि दोनों बेहतर और हीन शक्तियों को कैसे संभालना है।
3. वह जीत जाएगा जिसकी सेना अपने सभी रैंकों में समान भावना से एनिमेटेड है।
4. वह जीत जाएगा जिसने खुद को तैयार किया, दुश्मन को बिना तैयारी के ले जाने का इंतजार करता है।
5. वह जीत जाएगा जिसके पास सैन्य क्षमता है और वह संप्रभु के साथ हस्तक्षेप नहीं करता है। ”

package player;

import static zombie.Constants.CENTRE_OF_VISION;
import static zombie.Constants.SHOOT_RANGE;
import static zombie.Constants.VISION_RANGE;

import java.awt.Point;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

import zombie.Action;
import zombie.Move;
import zombie.Player;
import zombie.PlayerContext;
import zombie.PlayerId;
import zombie.Shoot;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Table.Cell;
import com.google.common.collect.TreeBasedTable;

    public class SunTzu implements Player {
        private TreeBasedTable<Integer, Integer, Integer> dangerZone;
        private final static int IN_ENEMY_RANGE = 5;
        private static final int IN_LOOTED_RANGE = 4;
        private static final int FULL_MAGAZINE = 10;
        private static final int IN_ZOMBIE_RANGE = 10;
        private static final int NUM_PLAYERS = 40;
        private LinkedHashSet<Point> safeSpots;
        private PlayerId[][] localAreas;
        private Set<PlayerId> looted= new HashSet<>(50*NUM_PLAYERS);
        private int ammo;
        PlayerId biggestThreat;
        private Set<PlayerId> shootable;
        private PlayerId myId;
        @SuppressWarnings("unused")
        @Override
        public Action doTurn(PlayerContext context) {
            ammo = context.getBullets();
            int gameTurn =context.getGameClock();
            int boardSize = context.getBoardSize();
            myId = context.getId();
            localAreas = context.getPlayField();
            dangerZone = TreeBasedTable.create();
            shootable = context.shootablePlayers();
            updateAdjacentBodyState();

            for (int x = CENTRE_OF_VISION - SHOOT_RANGE; x <= CENTRE_OF_VISION + SHOOT_RANGE; x++) {
                for (int y = CENTRE_OF_VISION - SHOOT_RANGE; y <= CENTRE_OF_VISION + SHOOT_RANGE; y++) {
                    PlayerId playerId = localAreas[x][y];
                    if (playerId != null) {
                        calculateDangerZone(x,y,playerId);
                    }
                }
            }
            Action myAction = null;
            Iterator<Point> pIt = safeSpots.iterator();
            if (ammo>0&&!pIt.hasNext()&&getBiggestThreat()!=null) {
                return new Shoot(getBiggestThreat());
            } else if (pIt.hasNext()){
                Point p=pIt.next();
                return Move.inDirection(p.x, p.y);
            }else{
                return Move.randomMove();
            }
        }

        private PlayerId getBiggestThreat() {
            return biggestThreat==null?shootable.iterator().next():biggestThreat;
        }

        public void setBiggestThreat(PlayerId biggestThreat) {
            this.biggestThreat = biggestThreat;
        }
        private void updateAdjacentBodyState() {

            for( int x = -1; x <= 1; x++ ) {
                for( int y = -1; y <= 1; y++ ) {
                    PlayerId adjPlayerId = localAreas[CENTRE_OF_VISION+x][CENTRE_OF_VISION+y];
                    if( adjPlayerId != null && (!looted.contains(adjPlayerId) && adjPlayerId.getName().equals("DeadBody"))) {
                        looted.add(adjPlayerId);
                    }       
                }
            }
        }

        private void calculateDangerZone(int x, int y, PlayerId playerId) {
            deriveDanger(playerId, x, y);
            safeSpots = getSafeSpots();
        }

        @SuppressWarnings("rawtypes")
        private LinkedHashSet<Point> getSafeSpots() {
            LinkedHashSet<Point> safeSpots = new LinkedHashSet<>();
            TreeSet<Cell> spots = new TreeSet<>(cellValueComparator());
            for (Cell<Integer, Integer, Integer> cell : dangerZone.cellSet()) {
                spots.add(cell);
            }
            final Cell safeCell = spots.isEmpty()?null:Collections.min(spots,cellValueComparator());
            Function<Cell,Point> pointFromCell = new Function<Cell,Point>() {
                public Point apply(final Cell arg0) {return new Point((int)arg0.getRowKey(), (int)arg0.getColumnKey());};
            };

            if (safeCell!=null) {
                safeSpots.addAll(Collections2.transform(
                        Collections2.filter(spots, sameCellValuePredicate(safeCell)), pointFromCell));
            }
            return safeSpots;
        }

        @SuppressWarnings("rawtypes")
        private Predicate<Cell> sameCellValuePredicate(final Cell safeCell) {
            return new Predicate<Cell>() {

                @Override
                public boolean apply(Cell arg0) {
                    return (arg0.getValue() == safeCell.getValue());
                }
            };
        }

        @SuppressWarnings("rawtypes")
        private Comparator<Cell> cellValueComparator() {
            return new Comparator<Cell>() {
                @Override
                public int compare(Cell o1, Cell o2) {
                    return (int)o1.getValue()- (int)o2.getValue();
                }
            };
        }

        private void deriveDanger(PlayerId playerId, int x, int y) {
            switch (playerId.getName()) {
            case "Gunner":
            case "Fox":
            case "HideyTwitchy":
            case "Shotguneer":
            case "ZombieRightsActivist":
            case "ZombieHater":
            case "SuperCoward":
            case "Sokie":
                updateDangerZoneWithEnemy(x, y);
                break;
            case "DeadBody":
            case "Zombie":
                updateDangerZoneWithBodies(x,y);
                break;
            default:
                break;
            }
        }

        private void updateDangerZoneWithBodies(int x, int y) {
            int dangerLevel=0;
            if(localAreas[x][y].getName().equalsIgnoreCase("Zombie")){
                dangerLevel = IN_ZOMBIE_RANGE;
            }
            else if(looted.contains(localAreas[x][y])){
                dangerLevel = IN_LOOTED_RANGE;
            }else{
                dangerLevel = Math.min(-1,-FULL_MAGAZINE+ammo);
            }
            for (int i = x-1; i < x+1; i++) {
                for (int j = y-1; j < y+1; j++) {
                    Integer previousDangerLevel = dangerZone.get(i, j) ;
                    int currentDangerLevel = dangerLevel;
                    if (previousDangerLevel != null) {
                        currentDangerLevel = previousDangerLevel+dangerLevel;
                    } 
                    dangerZone.put(x, y, currentDangerLevel);
                }
            }
        }

        private void updateDangerZoneWithEnemy(int x, int y) {
            int dangerLevel = IN_ENEMY_RANGE;
            playerShieldFound:
                for (int i = Math.max(x-SHOOT_RANGE, 0); i < Math.min(SHOOT_RANGE+x,VISION_RANGE); i++) {
                    for (int j = Math.max(y-SHOOT_RANGE, 0); j < Math.min(SHOOT_RANGE+y,VISION_RANGE); j++) {
                        int cardinalityFactor = (i+1)+(j+1);
                        Integer previousDangerLevel = dangerZone.get(i, j);
                        int currentDangerLevel = dangerLevel*cardinalityFactor;
                        PlayerId enemy = localAreas[x][y];
                        PlayerId target = localAreas[i][j];
                        if (target!=null) {
                            if (target != enemy) {
                                break playerShieldFound;
                            } else if (target.equals(myId)) {
                                setBiggestThreat(enemy);
                            }
                        }
                        if (previousDangerLevel != null) {
                            currentDangerLevel = Math.max(previousDangerLevel, dangerLevel);
                        } 
                        dangerZone.put(i, j, currentDangerLevel );
                    }
                }
        }

    }

वर्तमान मुद्दे यह हैं कि डेंजरज़ोन ठीक से नहीं बनाया गया है, और मुझे नहीं लगता कि सबसे बड़ी समस्या सही तरीके से आबाद हो रही है।


गुवा से कक्षाएं लेने के लिए +1। मैं भूल गया था कि मैंने इसे नियंत्रण कार्यक्रम में इस्तेमाल किया था, लेकिन इसमें इस तरह की चीज़ों के लिए बहुत सारी उपयोगी कक्षाएं हैं।
जेम्स_पिक

1
@james_pic tbh, मैं अपाचे समकक्ष के लिए बेचूंगा। ऐसा महसूस करें कि मैंने इसका एक हैश बनाया है।
प्योरफ्रेट

चूंकि यह मावेन के साथ बनाया गया है, इसलिए मैं किसी भी उचित निर्भरता को जोड़ सकता हूं जो आप चाहते हैं, अगर यह चीजों को आसान बनाता है। यदि आप कॉमन्स कलेक्शंस का उपयोग करना चाहते हैं, तो इसके लिए जाएं।
जेम्स_पिक

बात यह है, @james_pic मैं मुश्किल से इसे मावेन के साथ बनाने के लिए मिला क्योंकि मैं वास्तव में इसे समझ नहीं पाया हूं ... मैं इसके बजाय दूसरे के साथ काम करना चाहता हूं लेकिन अधिक काम करना।
प्युरफेरेट

1

टाइजॉइड - मेरा कुछ हद तक गूंगा रोबोट

package player;

import java.util.ArrayList;

import zombie.Action;
import zombie.Move;
import zombie.Player;
import zombie.PlayerContext;
import zombie.PlayerId;
import zombie.Shoot;

public class Tyzoid implements Player {
    private static final int minPathDistance = 7;
    private static final int pathLength = 10;
    private static final boolean debug = false;
    private static final int max_iterations = 5000;

    private int current_iterations = 0;

    private class Situation {
        public int hostiles = 0;
        public int scores[][] = new int[21][21];
        public ArrayList<Coordinate> path = new ArrayList<Coordinate>();
        public int distanceToHostile = 10;
        public Coordinate nearestHostile = new Coordinate(0,0);
        public boolean seriousHostile = false;

        // Minimum path score allowed to move under normal circumstances
        public int pathScore = -40;

        public int bulletsLeft = 0;

        public Situation(){
            path.add(new Coordinate(10,10));
        }
    }

    public class Coordinate {
        public int x = 0;
        public int y = 0;

        public Coordinate(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    @Override
    public Action doTurn(PlayerContext context) {
        try {
            Situation currentSituation = this.evaluateSituation(context);
            return this.makeDecision(currentSituation, context);
        } catch (Exception e) {
            if (debug) e.printStackTrace();
            return Move.STAY;
        }
    }

    private Situation evaluateSituation(PlayerContext context) {
        Situation situation = new Situation();

        for (int i = 0; i < 21; i++) {
            for (int j = 0; j < 21; j++) {
                situation.scores[i][j] = -3;
            }
        }

        situation.bulletsLeft = context.getBullets();

        PlayerId[][] visibleBoard = context.getPlayField();

        for (int bx = 0; bx < visibleBoard.length; bx++) {
            for (int by = 0; by < visibleBoard[bx].length; by++) {
                if (visibleBoard[bx][by] == null) {
                    continue;
                }

                if (this.isHostile(visibleBoard[bx][by].getName(), false)) {
                    situation.hostiles++;

                    this.hostileDetected(situation, bx, by, context);
                } else if (visibleBoard[bx][by].getName().equals("DeadPlayer")) {
                    this.friendlyDetected(situation, bx, by);
                    // OVER 9000!!! (there's an obstacle)
                    situation.scores[bx + 2][by + 2] = -9001;
                }
            }
        }

        return situation;
    }

    private Action makeDecision(Situation currentSituation, PlayerContext context) {
        if ((currentSituation.distanceToHostile < 3 || currentSituation.seriousHostile) && currentSituation.bulletsLeft > 0){
            // Shoot! (And possibly create opening!)
            PlayerId[][] visibleBoard = context.getPlayField();

            if (debug) System.out.println("Shooting!");

            return new Shoot(visibleBoard[currentSituation.nearestHostile.x-2][currentSituation.nearestHostile.y-2]);
        }

        if (currentSituation.hostiles > 6) {
            // Code red: get out of here! Trample over hostiles if necessary.
            // Guarantee path will generate, without hitting anything dead.
            currentSituation.pathScore = -9000;
        }

        findSafePath(currentSituation);

        Coordinate next = currentSituation.path.get(0);

        if (next.x == 10 && next.y == 10){
            if (debug) System.out.println("Staying Put.");
            return Move.STAY;
        }

        if (debug) System.out.println("Moving!");

        return Move.inDirection(next.x-2, next.y-2);
    }

    private void findSafePath(Situation currentSituation) {
        int x = 10;
        int y = 10;

        // Since we have a finite number of tiles, and we won't consider
        // backtracking, Let's consider every possible path to optimize the
        // safest path.

        current_iterations = 0;

        pathIteration(currentSituation, new ArrayList<Coordinate>(), x, y, 0);
    }

    private void pathIteration(Situation s, ArrayList<Coordinate> currentPath, int x, int y, int steps) {
        // If we've reached an end state,
        // Update situation if the currentPath has a higher (less negative) score than the current path.
        // As well as if we moved the minimum amount

        // Compute Score
        int score = 0;
        for (Coordinate c : currentPath) {
            score += s.scores[c.x][c.y];
        }

        int distanceTraveled = (Math.abs(10 - x) + Math.abs(10 - y));

        // Return if the currentPath has a lower score than the current path.
        if (score < s.pathScore || s.pathScore == 0 || current_iterations > max_iterations) return;

        if (debug) System.out.println("debug: step " + steps + " (" + score + " : " + s.pathScore + ") Distance: " + distanceTraveled);

        // Prevent my algorithm from blowing up the whole works
        current_iterations++;

        if (steps == pathLength) {
            if (distanceTraveled >= minPathDistance) {
                if (score > s.pathScore) {
                    s.path = currentPath;
                    s.pathScore = score;
                }
            }

            return;
        }

        ArrayList<Coordinate> searched = new ArrayList<Coordinate>();
        for (int index = 0; index < 9; index++){
            int minx = 0, miny = 0;
            int minscore = -1000;

            for (int i = -1; i < 2; i++) {
                for (int j = -1; j < 2; j++) {
                    if (searched.contains(new Coordinate(x+i, y+j)) || currentPath.contains(new Coordinate(x+i, y+j))){
                        continue;
                    }

                    if (steps > 1){
                        Coordinate c0 = currentPath.get(steps-2);
                        Coordinate c1 = currentPath.get(steps-1);

                        int dx = c1.x-c0.x;
                        int dy = c1.y-c0.y;

                        // Disable turning more than 45 degrees
                        if (dy != j && dx != i) continue;
                    }

                    if (s.scores[x+i][y+j] > minscore){
                        minx = x+i;
                        miny = y+j;
                        minscore = s.scores[x+i][y+j];
                    }
                }
            }

            if (!currentPath.contains(new Coordinate(minx, miny))) {
                ArrayList<Coordinate> newPath = (ArrayList<Coordinate>) currentPath.clone();
                newPath.add(new Coordinate(minx, miny));
                pathIteration(s, newPath, minx, miny, steps + 1);
            }

            searched.add(new Coordinate(minx, miny));
        }
    }

    private void hostileDetected(Situation seriousSituation, int bx, int by, PlayerContext context) {
        boolean verySerious = false;
        if (this.isHostile(context.getPlayField()[bx][by].getName(), true) && context.shootablePlayers().contains(context.getPlayField()[bx][by])){
            seriousSituation.seriousHostile = true;
            verySerious = true;
        }

        for (int i = -4; i < 5; i++) {
            for (int j = -4; j < 5; j++) {
                // Prevent from overflowing the path matrix.
                if (i + bx + 2 < 0 || i + bx + 2 > 20 || j + by + 2 < 0 || j + by + 2 > 20) continue;

                int separationLevels = Math.max(Math.abs(i), Math.abs(j));
                seriousSituation.scores[bx + i + 2][by + j + 2] += separationLevels*2 - 10;
            }
        }

        int distanceToHostile = Math.abs(10 - (bx + 2)) + Math.abs(10 - (by + 2));
        if ((distanceToHostile < seriousSituation.distanceToHostile && !seriousSituation.seriousHostile) || verySerious){
            seriousSituation.nearestHostile = new Coordinate(bx + 2, by + 2);
            seriousSituation.distanceToHostile = distanceToHostile;
        }
    }

    private void friendlyDetected(Situation lessBleakSituation, int bx, int by) {
        for (int i = -4; i < 5; i++) {
            for (int j = -4; j < 5; j++) {
                // Prevent overflowing the path matrix.
                if (i + bx < 0 || i + bx > 20 || j + by < 0 || j + by > 20) continue;

                int separationLevels = Math.max(Math.abs(i), Math.abs(j));
                lessBleakSituation.scores[bx + i + 2][by + j + 2] += 4 - separationLevels;
            }
        }
    }

    private boolean isHostile(String name, boolean serious){
        // Generated from a list of players who shot me during testing.
        // If anyone adds me as a 'friendly', I'd be happy to reciprocate.
        switch(name){
            case "Bee":
            case "Coward":
            case "Fox":
            case "Gunner":
            case "HideyTwitchy":
            case "Sokie":
            case "ZombieHater":
            case "ZombieRightsActivist":
                return true;
            default:
                return (!serious && name.equals("Zombie")); // Zombies don't shoot
        }
    }
}

मुझे डर है कि आपको जीतने का मौका मिलने में थोड़ी देर हो जाएगी, लेकिन अगर मुझे बाद में मौका मिलता है, तो मैं आपकी प्रविष्टि के साथ एक और रन करूंगा, यह देखने के लिए कि आप कैसे किराया लेते हैं।
जेम्स_पिक

हाँ, मैंने अपना सबमिशन जमानत के समय के आधार पर प्रस्तुत किया: / - मुझे उम्मीद नहीं है कि मैं इसके करीब जाऊंगा ... हालांकि बॉट बहुत अच्छा नहीं है।
Tyzoid

1
इसके बारे में क्षमा करें, बाउंटी को 3 अगस्त की निर्धारित तिथि के बाद दिन के समय के लिए सेट किया गया था ताकि मैं इसे आज, 4 अगस्त को पुरस्कार दे सकूं। (कहा जा रहा है कि आप सभी को गोली मारते हैं जो मेरे दोनों पात्रों में से किसी एक को शूट करते हैं इसलिए मुझे टाइजॉइड के लिए निहित होना चाहिए।)
kaine
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.